我正在为一些小作业(100到700微秒)编写一个简单的线程池。我只使用两个线程(因为只有两个作业,处理器只有两个核心)。我的问题是大多数时候两个作业都是由同一个线程执行的。较大的作业(几毫秒)不会出现此问题。
预期的行为是(在这种情况下,加速是预期的:
但有时(50%)(其他线程在cond中的互斥锁被阻止之前被阻止通知?):
或更糟糕的是(其他线程丢失的信号?):
这是两个线程执行的主循环(使用pthread_create创建):
pthread_mutex_lock(&pl->mutex);
for (;;) {
/* wait on notification that a new job is available */
while (pl->queue_head==NULL) {
//printf("Thread %d before cond_wait\n",threadID);
pthread_cond_wait(&pl->workcv, &pl->mutex);
//printf("Thread %d after cond_wait\n",threadID);
}
/* get first job */
job=pl->queue_head;
if (job!=NULL) {
/* remove job from the queue */
pl->queue_head=job->next;
if (job==pl->queue_tail){
pl->queue_tail=NULL;
}
pthread_mutex_unlock(&pl->mutex);
/* get job parameter */
func=job->func;
arg=job->arg;
/* Execute job */
//printf("Job executed by: %d\n",threadID);
func(arg, threadID);
/* acquire lock */
pthread_mutex_lock(&pl->mutex);
}
}
在提交作业之前,两个线程都在workcv条件下等待while循环。作业由以下代码行提交(在两个代码片段中,我删除了用于等待两个作业完成的代码):
pthread_mutex_lock(&pl->mutex);
/* Append job to queue */
if (pl->queue_head==NULL) {
pl->queue_head=job[numJobs-1];
}else {
pl->queue_tail->next=job[numJobs-1];
}
pl->queue_tail=job[0];
/* Wake up thread if one is idle */
pthread_cond_broadcast(&pl->workcv);
pthread_mutex_unlock(&pl->mutex);
使用互斥锁,线程和条件的默认属性。 环境:Gcc 4.2.1,Mac OSX Snow Leopard
我做错了什么?
谢谢!
答案 0 :(得分:1)
而不是pthread_cond_broadcast()
,您应该使用pthread_cond_signal()
。此外,在线程完成一项工作后,它应该发出条件变量信号:
/* remove job from the queue */
pl->queue_head=job->next;
if (job==pl->queue_tail){
pl->queue_tail=NULL;
}
if (pl->queue_head != NULL)
pthread_cond_signal(&pl->workcv);
pthread_mutex_unlock(&pl->mutex);