在了解了线程的接口函数后,同共享内存一样,接下来将对线程类进行封装。
直接上代码:
BaseThread.h
#ifndef BASETHREAD_H_
#define BASETHREAD_H_
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
class CBaseThread
{
public:
CBaseThread(); //此时还没有创建线程,只有类对象
~CBaseThread();
void start(); //创建线程并启动线程
virtual int run() = 0; //用户自定义处理函数,在派生类中必须实现
protected:
pthread_t m_tid; //线程ID
bool m_bRun; // 运行标记
private:
static void * rountine(void *arg); //线程类处理函数框架
};
#endif
头文件分析
rountine函数的作用:前面提到线程的create函数第三个参数是需要一个函数指针的,这里rountine函数就是这样一个函数指针,具体的函数体内部将在cpp中呈现。
start函数的作用:一个线程对象在创建的时候未必需要运行起来,所以在构造函数中,仅仅是建了一个空壳,直到start函数被调用的时候,线程被create出来,并且跑rountine函数。
run函数作用:真正要跑的函数体,由于每个线程要执行的功能可能各不相同,这里将run函数设置为虚函数,后续继承这个类的函数只需重载run函数即可。至于run函数了rountine函数的联系在下方cpp文件中可以看出。
BaseThread.cpp
#include "BaseThread.h"
CBaseThread::CBaseThread()
:m_bRun(false)
{
}
CBaseThread::~CBaseThread()
{
}
void CBaseThread::start()
{
if (m_bRun == false) //m_bRun为线程是否已经在运行了
{
if( pthread_create(&m_tid,NULL,rountine,(void *)this) != 0)
{
perror("create thread error : ");
}
}
}
void * CBaseThread::rountine(void *arg)
{
pthread_detach(pthread_self()); //自分离线程,不用调用join函数等待
CBaseThread *thr = (CBaseThread *)arg;
thr->m_bRun = true;
thr->run(); //用户自定义的处理函数
thr->m_bRun = false;
pthread_exit(NULL);
}
cpp文件分析
由以上代码可以得出,rountine函数在start时被调用到,然后rountine内部再跑不同的run函数,这样就有了一个完整的框架:
构造->start->rountine->run
线程封装测试代码
结合共享内存的测试代码,
写端代码
#include<iostream>
#include"ShmFIFO.h"
#include<sys/types.h>
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#define key 7777
using namespace std;
int main()
{
CShmFIFO fifo(key,1024,10);
char buffer[2048] = {0};
while(1)
{
printf("write your words:");
fgets(buffer,2048,stdin);
fifo.write((const char *)buffer);
if(strncmp(buffer,"end",3) == 0)
{
printf("ending write\n");
break;
}
sleep(2);
}
}
读端代码
#include<iostream>
#include"ShmFIFO.h"
#include<sys/types.h>
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include"GetFIFOThread.h"
#define key 7777
using namespace std;
CShmFIFO fifo(key,1024,10);
int main()
{
CGetFIFOThread read_thread;
read_thread.start();
printf("back is running,waiting for news\n");
while(1);
}
继承BaseThread类的CGetFIFOThread类代码
cpp
#include<iostream>
#include<string.h>
#include"GetFIFOThread.h"
#include<string.h>
using namespace std;
extern CShmFIFO fifo;
CGetFIFOThread::CGetFIFOThread()
{
memset(buffer,0,1024);
}
CGetFIFOThread::~CGetFIFOThread()
{}
int CGetFIFOThread::run()
{
while(1)
{
fifo.read(buffer);
printf("get news : %s",buffer);
if(strncmp(buffer,"end",3) == 0)
{
printf("read_thread is ending");
break;
}
}
return 0;
}
头文件
#ifndef _GETFIFOTHREAD_H
#define _GETFIFOTHREAD_H
#include"ShmFIFO.h"
#include"./BaseThread.h"
class CGetFIFOThread : public CBaseThread
{
public:
CGetFIFOThread();
~CGetFIFOThread();
int run();
private:
char buffer[1024];
};
#endif
测试结果

结果分析:
前端写信息给后端,后端有一个getfifo线程可以不断从共享内存中读取信息并且打印出来,并且后端主线程堵塞在while(1)循环,证明线程类封装成功,并且和共享内存有了很好的结合。
本文介绍了如何在Linux环境下对线程进行封装,通过BaseThread类实现线程创建与管理。文章详细分析了BaseThread.h和BaseThread.cpp文件,讲解了rountine和run函数的作用,以及如何通过start函数启动线程执行任务。同时,给出了线程封装的测试代码,包括写端和读端的实现,并展示了如何通过继承BaseThread类创建特定功能的CGetFIFOThread类,成功与共享内存结合,实现了信息的读取和打印。
885

被折叠的 条评论
为什么被折叠?



