* 定义任务类
class Job
{
Job(void*(*p)(void*),void * a) : process(p),arg(a),next(NULL){}
void * (* process)(void *);
void * arg;
Job * next;
};
任务类的 process 参数是每个线程要执行的函数的指针,arg 为传入该函数的参数
* 定义线程池类
class Pool
{
friend void * thread_contrl(void*);
public:
Pool(int num):max_thread_num(num) //构造函数必须给出线程池中线程的数量
{
pthread_mutex_init(&queue_lock,NULL);
pthread_cond_init(&queue_cond,NULL);
threadid = new pthread_t[num];
shutdown = false;
for(int i(0); i != num; ++i)
{
//线程池中每个线程均执行 thread_contrl(void *) 函数,参数为 Pool*
//线程通过 thread_contrl 进行调控,并在其内部进行线程任务分配
pthread_create(&threadid[i],NULL,thread_contrl,this);
}
}
void add_job(void * (* process)(void *),void * arg)
{
Job * temp = new Job(process,arg);
//在任务队列中增加新任务,需要先通过上锁进行访问
pthread_mutex_lock(&queue_lock);
queue_q.push(temp);
pthread_mutex_unlock(&queue_lock);
//发送任务进入信号,唤醒等待线程
pthread_cond_signal(&queue_cond);
}
~Pool()
{
if(shutdown)
return;
//唤醒所有线程
pthread_cond_broadcast(&queue_cond);
for(int i(0); i < max_thread_num; ++i)
{
//等待线程结束
pthread_join(threadid[i],NULL);
}
delete []threadid;
Job * temp = NULL;
while(!queue_q.empty())
{
temp = queue_q.front();
queue_q.pop();
delete temp;
temp = 0;
}
pthread_mutex_destroy(&queue_lock);
pthread_cond_destroy(&queue_cond);
}
queue<Job *> queue_q;
pthread_mutex_t queue_lock;
pthread_cond_t queue_cond;
pthread_t * threadid;
int max_thread_num;
bool shutdown; //线程池开关信号
};
* 定义线程控制函数 void * thread_contrl(void * arg)
void * thread_contrl(void * arg)
{
Pool * pool = reinterpret_cast<Pool *>(arg);
while(1)
{
//需要获得线程池 pool 中的任务,因此在访问任务列表前需要上锁
pthread_mutex_lock(&pool->queue_lock);
#ifndef WORK //用于调试信息的输出
cout << "starting thread : " << pthread_self() << endl;
#endif
while(pool->queue_q.empty() && pool->shutdown == false)
{
#ifndef WORK
cout << "thread : " << pthread_self() << " is waiting"<< endl;
#endif
pthread_cond_wait(&pool->queue_cond,&pool->queue_lock);
}
if(pool->shutdown) //线程池关闭信号打开
{
pthread_mutex_unlock(&pool->queue_lock);
pthread_exit(NULL);
}
#ifndef WORK
cout << "thread : " << pthread_self() << " is starting working"<< endl;
#endif
//从任务列表中领取一项任务
Job * temp = pool->queue_q.front();
pool->queue_q.pop();
pthread_mutex_unlock(&pool->queue_lock);
//获得任务的线程执行领取的任务
*(temp->process)(temp->arg);
delete temp;
temp = 0;
}
}
*使用实例:
void * test(void * arg)
{
int num = reinterpret_cast<int>(arg);
printf("%d\n",num);
//***使用 printf 而不使用 cout 的原因之后描述
sleep(1);
return NULL;
}
int main()
{
Pool * pool = new Pool(3); //建立三线程的线程池
for(int i (0); i < 10; ++i)
{
pool->add_job(test,reinterpret_cast<void*>(i));
}
sleep(6);
printf("end main\n");
}
输出结果为:每三个连续输出,后停顿一秒,输出下三个,因为线程池中是三线程,此时是三线程同步跑
多线程中使用 printf 而不使用 cout 的原因:printf()函数的输出是一次函数调用,此时输出不会被打断;而cout函数而言,<< 操作符的每次使用都是一次函数调用,有可能在每次<<调用之间线程被调度,使得输出被打断。因此在多线程输出中使用 printf 比使用 cout 好