gpt4 book ai didi

c - 理解 pthread_cond_wait() 和 pthread_cond_signal()

转载 作者:太空宇宙 更新时间:2023-11-04 02:52:57 24 4
gpt4 key购买 nike

我以这段代码为例,其中创建了两个线程,然后它看起来像一个 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

最佳答案

实际上,只有一个线程被唤醒,您无法控制它是哪一个。

(pthread_cond_signal 唤醒至少一个等待给定条件变量的线程,选择的线程由调度策略决定。)

在您的情况下,您需要重新考虑条件变量 (condvar) 表示的“条件”的含义。

如果 condvar 确实意味着 “生产者已将一个项目添加到多个队列之一,每个队列都有一个专用的消费者”, 那么您应该 pthread_cond_broadcast 唤醒每个队列的消费者,让被唤醒的线程判断是否有工作要做。或者,您可以将条件重铸为“生产者已将一个项目添加到此队列,该队列有一个专门的消费者”,并为每个队列使用一个条件变量。

关于c - 理解 pthread_cond_wait() 和 pthread_cond_signal(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20277033/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com