参考链接
[1]. Linux 线程池的概念与实现
[2]. 【C语言】如何理解【void(*)(void)】
[3]. 关于typedef void (*sighandler_t)(int)的理解
[4]. C++类中this指针的理解
[5]. C++ 调用PTHREAD_CREATE函数时,传入类中的成员报错。解决方法。
[6]. C++ pthread_create传递静态函数及其参数
[7]. 对于void* 的理解
问题引入
C++中线程传入类内成员函数时,需要将该成员函数定义为静态成员函数[1]):
//threadpool.hpp
#include <iostream>
#include <cstdio>
#include <queue>
#include <stdlib.h>
#include <pthread.h>
using namespace std;
typedef void (*handler_t)(int);
#define MAX_THREAD 5
//任务类
class ThreadTask
{
public:
ThreadTask()
{
}
//将数据与处理方式打包在一起
void setTask(int data, handler_t handler)
{
_data = data;
_handler = handler;
}
//执行任务函数
void run()
{
return _handler(_data);
}
private:
int _data;//任务中处理的数据
handler_t _handler;//处理任务方式
};
//线程池类
class ThreadPool
{
public:
ThreadPool(int thr_max = MAX_THREAD)
:_thr_max(thr_max)
{
pthread_mutex_init(&_mutex, NULL);
pthread_cond_init(&_cond, NULL);
for (int i = 0; i < _thr_max; i++)
{
pthread_t tid;
int ret = pthread_create(&tid, NULL, thr_start, this);
if (ret != 0)
{
printf("thread create error\n");
exit(-1);
}
}
}
~ThreadPool()
{
pthread_mutex_destroy(&_mutex);
pthread_cond_destroy(&_cond);
}
bool taskPush(ThreadTask &task)
{
pthread_mutex_lock(&_mutex);
_queue.push(task);
pthread_mutex_unlock(&_mutex);
pthread_cond_signal(&_cond);
return true;
}
//类的成员函数,有默认的隐藏参数this指针
//置为static,没有this指针,
static void *thr_start(void *arg)
{
ThreadPool *p = (ThreadPool*)arg;
while (1)
{
pthread_mutex_lock(&p->_mutex);
while (p->_queue.empty())
{
pthread_cond_wait(&p->_cond, &p->_mutex);
}
ThreadTask task;
task =p-> _queue.front();
p->_queue.pop();
pthread_mutex_unlock(&p->_mutex);
task.run();//任务的处理要放在解锁之外
}
return NULL;
}
private:
int _thr_max;//线程池中线程的最大数量
queue<ThreadTask> _queue;//任务缓冲队列
pthread_mutex_t _mutex; //保护队列操作的互斥量
pthread_cond_t _cond; //实现从队列中获取结点的同步条件变量
};
上面代码中:
class T.. {
int ret = pthread_create(&tid, NULL, thr_start, this);
...
}
在类中thr_strat定义为:
//类的成员函数,有默认的隐藏参数this指针
//置为static,没有this指针,
static void *thr_start(void *arg)
{
ThreadPool *p = (ThreadPool*)arg;
while (1)
{
pthread_mutex_lock(&p->_mutex);
while (p->_queue.empty())
{
pthread_cond_wait(&p->_cond, &p->_mutex);
}
ThreadTask task;
task =p-> _queue.front();
p->_queue.pop();
pthread_mutex_unlock(&p->_mutex);
task.run();//任务的处理要放在解锁之外
}
return NULL;
}
类的成员函数,有默认的隐藏参数this指针,设为为static,没有this指针是什么意思?
为何要将成员函数设为static?
类中this的返回值是什么?
错误出现在哪?
运行报错,第三个参数类型不匹配:
pthread函数原型
头文件
#include <pthread.h>
函数声明:
int pthread_create(pthread_t *tidp, const pthread_attr_t *attr,
( void *)(*start_rtn)( void *), void *arg);
若线程创建成功,则返回0。若线程创建失败,则返回出错编号;
(对于(void*) (*) (void*)
指一个参数为void*,返回值为void*的函数指针[2][3] )
参数
第一个参数为指向线程 标识符的 指针。
第二个参数用来设置线程属性,一般为NULL。
第三个参数是线程运行函数的起始地址。
最后一个参数是运行函数的参数。
解决
C++中,我们知道在类中成员函数调用类内的成员变量或成员函数时,会隐式调用this指针[4][5],也就是说,上例中类成员函数加上this指针后,类型为void* (Box::) (void*)
的成员函数指针,而pthread_create参数类型为void* (*) (void*)
两个不同的类型,肯定不会匹配。
既然错误出现在类中成员被隐式加上this,那么加上static变为静态成员函数以后,就不会加上this指针。
静态成员函数不能访问类内的非静态成员,但只需要在pthread_create时将this指针传入,就可以使得静态成员函数访问类内非静态成员[5]。
传入成员函数参数
上面如果需要给函数传入其他参数,可以使用数组的方式[6]