本文主要是介绍线程池封装成类的选择,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1.由于线程pthread_create中的回调函数是void*(*fun)(void*)的形式。
而封装在类中的线程的运行函数是void *ThreadWorker()的形式,因此声明一个类型别名typedef void*(*Thread)(void *)。
在调用pthread_create时,进行强制类型转化,并把类的this指针传递给ThreadWorker函数。
if(pthread_create(&threads[i],NULL,Thread(&ThreadPool::ThreadWorker),(void *)this)!=0)
这样可以进行封装线程池,但每次编译时会出现warning信息(开启g++ -Wall选项)。
2.将线程的运行函数写成static的形式。
static void *worker(void *);// 多线程运行函数
实际的运行函数写成
void *run();//线程实际运行函数
由于worker是静态成员函数,只能调用静态成员,worker传递的参数为ThreadPool类型的指针,只能调用ThreadPool指针
运行run函数。
void *ThreadPool::worker(void *arg)
{
ThreadPool * pool=(ThreadPool *) arg;
pool->run();
return pool;
}
构造函数中新建线程语句如下:
if(pthread_create(&threads[i],NULL,worker,(void *)this)!=0)
run函数定义如下:
void *ThreadPool::run()
{
while(1)
{
pthread_mutex_lock(&p_mutex);
while(!stop && tasks.empty())//当任务队列为空时一直等待,防止出现两个线程处理同一个任务的情况
pthread_cond_wait(&p_cond,&p_mutex);
if(stop)
break;
auto task=tasks.front();
tasks.pop();
pthread_mutex_unlock(&p_mutex);
(*(task.function))(task.argument);
}
pthread_exit(NULL);
}
这篇关于线程池封装成类的选择的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!