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

本文介绍了如何在Linux环境下对线程进行封装,通过BaseThread类实现线程创建与管理。文章详细分析了BaseThread.h和BaseThread.cpp文件,讲解了rountine和run函数的作用,以及如何通过start函数启动线程执行任务。同时,给出了线程封装的测试代码,包括写端和读端的实现,并展示了如何通过继承BaseThread类创建特定功能的CGetFIFOThread类,成功与共享内存结合,实现了信息的读取和打印。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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)循环,证明线程类封装成功,并且和共享内存有了很好的结合。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值