在了解了线程的接口函数后,同共享内存一样,接下来将对线程类进行封装。
直接上代码:

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

测试结果

记linux下对线程的学习(二)--对基本线程类的封装

结果分析:

前端写信息给后端,后端有一个getfifo线程可以不断从共享内存中读取信息并且打印出来,并且后端主线程堵塞在while(1)循环,证明线程类封装成功,并且和共享内存有了很好的结合。

相关文章:

  • 2022-12-23
  • 2021-12-09
  • 2022-12-23
  • 2021-12-04
  • 2022-12-23
  • 2021-08-13
  • 2022-01-19
  • 2021-12-10
猜你喜欢
  • 2021-11-26
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案