我将此代码作为一个示例,其中创建了两个线程,然后看起来像pthread_cond_wait()用于挂起该线程,直到它准备好通过使用pthread_cond_signal()再次工作。我的问题是,如果多个线程同时等待?如何执行pthread_cond_signal()选择正确的线程来唤醒?有没有办法选择一个特定的线程来唤醒?假设我有一个生产者线程,它将客户订单放入单独的队列,每个队列由一个线程管理。如果两个消费者线程挂起了wait(),因为它们的队列中没有任何东西,但是生产者线程只在一个消费者队列中插入一个订单,我们如何区分?如果这不可能,那么我可以使用其他方法来实现我想要的东西吗?
这是一个示例代码,因为stackoverflow喜欢代码......不相关: 实施例
#define _MULTI_THREADED
#include <pthread.h>
#include <stdio.h>
#include "check.h"
/* For safe condition variable usage, must use a boolean predicate and */
/* a mutex with the condition. */
int workToDo = 0;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
#define NTHREADS 2
void *threadfunc(void *parm)
{
int rc;
while (1) {
/* Usually worker threads will loop on these operations */
rc = pthread_mutex_lock(&mutex);
checkResults("pthread_mutex_lock()\n", rc);
while (!workToDo) {
printf("Thread blocked\n");
rc = pthread_cond_wait(&cond, &mutex);
checkResults("pthread_cond_wait()\n", rc);
}
printf("Thread awake, finish work!\n");
/* Under protection of the lock, complete or remove the work */
/* from whatever worker queue we have. Here it is simply a flag */
workToDo = 0;
rc = pthread_mutex_unlock(&mutex);
checkResults("pthread_mutex_lock()\n", rc);
}
return NULL;
}
int main(int argc, char **argv)
{
int rc=0;
int i;
pthread_t threadid[NTHREADS];
printf("Enter Testcase - %s\n", argv[0]);
printf("Create %d threads\n", NTHREADS);
for(i=0; i<NTHREADS; ++i) {
rc = pthread_create(&threadid[i], NULL, threadfunc, NULL);
checkResults("pthread_create()\n", rc);
}
sleep(5); /* Sleep is not a very robust way to serialize threads */
for(i=0; i<5; ++i) {
printf("Wake up a worker, work to do...\n");
rc = pthread_mutex_lock(&mutex);
checkResults("pthread_mutex_lock()\n", rc);
/* In the real world, all the threads might be busy, and */
/* we would add work to a queue instead of simply using a flag */
/* In that case the boolean predicate might be some boolean */
/* statement like: if (the-queue-contains-work) */
if (workToDo) {
printf("Work already present, likely threads are busy\n");
}
workToDo = 1;
rc = pthread_cond_signal(&cond);
checkResults("pthread_cond_broadcast()\n", rc);
rc = pthread_mutex_unlock(&mutex);
checkResults("pthread_mutex_unlock()\n", rc);
sleep(5); /* Sleep is not a very robust way to serialize threads */
}
printf("Main completed\n");
exit(0);
return 0;
}
Output:
Enter Testcase - QP0WTEST/TPCOS0
Create 2 threads
Thread blocked
Thread blocked
Wake up a worker, work to do...
Thread awake, finish work!
Thread blocked
Wake up a worker, work to do...
Thread awake, finish work!
Thread blocked
Wake up a worker, work to do...
Thread awake, finish work!
Thread blocked
Wake up a worker, work to do...
Thread awake, finish work!
Thread blocked
Wake up a worker, work to do...
Thread awake, finish work!
Thread blocked
Main completed
答案 0 :(得分:2)
实际上,只有一个线程被唤醒,你无法控制它是哪一个。
(pthread_cond_signal
唤醒至少一个等待给定条件变量的线程,所选线程由调度策略确定。)
在您的情况下,您需要重新考虑条件变量(condvar)所代表的“条件”的含义。
如果condvar确实意味着“生产者已经将项目添加到多个队列之一,每个队列中都有一个专用的消费者”,那么你应该pthread_cond_broadcast
唤醒每个队列的消费者让被唤醒的线程弄清楚是否有工作要做。或者,您可以将条件重新设置为“生产者已将项目添加到此队列,该项目具有专用的消费者”,并为每个队列使用一个condvar。