【发布时间】:2011-03-24 14:58:44
【问题描述】:
我正在为一些小型作业(100 到 700 微秒)编写一个简单的线程池。我只使用两个线程(因为只有两个作业并且处理器只有两个内核)。我的问题是大多数时候这两个作业都是由同一个线程执行的。较大的作业(几毫秒)不会出现此问题。
预期的行为将是(在这种情况下,加速是预期的:
- cond_wait 之后的线程 1
- 作业执行者:1
- cond_wait 之后的线程 0
- 作业执行者:0
- cond_wait 之前的线程 1
- cond_wait 之前的线程 0
但有时(50 %)(其他线程在 cond 中的互斥锁之前阻塞没有通知?):
- cond_wait 之后的线程 1
- 作业执行者:1
- 作业执行者:1
- cond_wait 之后的线程 0
- cond_wait 之前的线程 0
- cond_wait 之前的线程 1
甚至更糟(其他线程的信号丢失?):
- cond_wait 之后的线程 0
- 作业执行者:0
- 作业执行者:0
- cond_wait 之前的线程 0
这是两个线程执行的主循环(使用 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 循环中等待。作业由以下代码行提交(在两个代码 sn-ps 中,我删除了用于等待两个作业完成的代码):
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
我做错了什么?
谢谢!
【问题讨论】:
标签: c mutex conditional-statements pthreads