1.用C语言中的线程封装一个C++线程基类
线程基类的优点
-
灵活性:可被继承的线程基类可以灵活地根据具体需求进行扩展和定制。你可以在派生类中添加额外的成员函数、成员变量,以及自定义的线程操作接口。这使得你可以更好地适应复杂的应用需求。
-
可定制性:通过可被继承的线程基类,你可以实现自己的线程管理策略、线程间通信机制等。你可以定义自己的线程调度算法,控制线程的执行顺序和优先级等。这样可以更好地满足特定场景下的需求。
-
可扩展性:当你的应用需要多线程之间的协作和通信时,你可以在可被继承的线程基类中定义线程间的通信机制,例如消息队列、互斥锁、条件变量等。这样可以更方便地在多线程环境中实现数据的共享和同步。
-
易于维护:使用可被继承的线程基类,你可以将线程相关的代码封装在一个类中,并在该类中提供统一的接口和操作。这使得代码更模块化、可读性更好,并且易于维护和调试。
std::thread 的相对缺点
当继承std::thread类时会面临一些潜在问题,主要是由于std::thread类的设计和语义的限制导致的。下面是几个需要考虑的问题:
-
缺乏虚析构函数:std::thread类没有虚析构函数,这意味着当你使用继承方式时,如果基类的指针指向派生类对象,并且在派生类对象上调用delete操作符,只会调用基类的析构函数,而不会调用派生类的析构函数。这可能导致资源泄漏或未定义的行为。
-
禁止复制和移动:std::thread类禁止了复制和移动语义,也就是说,你不能直接复制或移动派生类的实例。这可能限制了一些你希望在派生类中使用的语言特性,例如容器中存储派生类对象或者将派生类对象作为函数参数传递。
-
不可继承的成员函数:std::thread类提供了一些成员函数,如join()、detach()等,这些函数不能被派生类继承或重载。因此,在派生类中无法直接重写这些函数,而只能通过其他方式来实现类似的功能。
以下是使用pthread重新编写的c++线程基类
freertos,rtos也可以用相同的方法来实现
/**
******************************************************************************
* @file threadbase.cpp
* @author cj
* @version V1.0
* @date 2021/10
* @brief
******************************************************************************
* @attention
******************************************************************************
*/
#include "threadbase.h"
#include "typedef.h"
#include <stdio.h>
ThreadBase::ThreadBase() :
tid(0)
{
}
ThreadBase::~ThreadBase()
{
printf("~ThreadBase\n");
}
bool ThreadBase::start()
{
int ret = 0;
ret = pthread_attr_init(&t_attr);
if(ret != 0)
{
perror("pthread_attr_init");
return false;
}
/* Sets the stack size for the thread */
/*
ret = pthread_attr_setstacksize(&t_attr, max_pthread_size);
if(ret != 0)
{
perror("pthread_attr_getstacksize");
return false;
}
*/
ret = pthread_create(&tid, &t_attr, work, this);
if(ret != 0)
{
perror("pthread_create");
return false;
}
return true;
}
void ThreadBase::routine()
{
}
pthread_t ThreadBase::self()
{
if(!tid)
{
tid = pthread_self();
}
return tid;
}
int ThreadBase::equal(pthread_t t)
{
int ret = 0;
ret = pthread_equal(tid, t);
return (ret)?0:-1;
}
int ThreadBase::detach()
{
return pthread_detach(tid);
}
int ThreadBase::join(pthread_t t)
{
return pthread_join(t, NULL);
}
int ThreadBase::exit()
{
int ret = 0;
pthread_exit(NULL);
return ret;
}
int ThreadBase::cancel(pthread_t t)
{
return pthread_cancel(t);
}
int ThreadBase::destroy()
{
return cancel(tid);
}
void ThreadBase::cleaner(void *pHandle)
{
ThreadBase *p = (ThreadBase *)pHandle;
delete p;
p = NULL;
printf("after clean\n");
}
void *ThreadBase::work(void *pHandle)
{
ThreadBase* pThread = (ThreadBase *)pHandle;
/* Register thread handling functions */
pthread_cleanup_push(cleaner, pHandle);
/* Thread-run function */
pThread->routine();
/* The thread resource is released. The parameter is non-0 */
pthread_cleanup_pop(1);
return NULL;
}
#ifndef THREADBASE_H
#define THREADBASE_H
#include <pthread.h>
class ThreadBase
{
public:
ThreadBase();
virtual ~ThreadBase();
virtual bool start(); // Starting a thread
virtual void routine(); // running function of a thread, implemented by a derived class
virtual pthread_t self(); // Get the thread number of the current thread
virtual int equal(pthread_t t); // Compares whether the thread numbers are equal
virtual int detach(); // Separate thread
virtual int join(pthread_t t); // Connection thread
virtual int exit(); // Thread to exit
virtual int cancel(pthread_t t); // Cancel the thread
virtual int destroy(); // Destruction of the thread
private:
static void cleaner(void *pHandle); // Thread cleanup function
static void *work(void *pHandle); // Thread callback function
private:
pthread_attr_t t_attr; // Thread attributes
pthread_t tid; // The thread number
const unsigned int max_pthread_size = 8 * 1024; // Thread stack size
};
#endif
2.线程基类的使用
#include "threadbase.h"
class MyTask: public ThreadBase
{
public:
MyTask();
~MyTask();
void routine();
protected:
};
#endif
#include "mytask.h"
MyTask::MyTask()
{
cjdebug("MyTask is new\n");
}
MyTask::~MyTask()
{
...
}
void MyTask::routine()
{
cjdebug("Comm is running\n");
while(true)
{
...
}
}
3. 使用标准 std::thread
以下代码展示std::thread是如何使用的
MyThread
的类,并在类中组合了一个std::thread对象来实现
#include <iostream>
#include <thread>
class MyThread
{
public:
MyThread() : thread_() {}
~MyThread()
{
if (thread_.joinable())
{
thread_.join();
}
}
void Start()
{
// 启动线程
thread_ = std::thread(&MyThread::Run, this);
}
void Join()
{
// 等待线程执行完毕
if (thread_.joinable())
{
thread_.join();
}
}
private:
void Run()
{
// 线程操作
std::cout << "Thread function" << std::endl;
}
std::thread thread_;
};
int main()
{
std::cout << "Main thread" << std::endl;
MyThread myThread;
myThread.Start();
// 主线程继续执行其他操作
myThread.Join();
return 0;
}