gpt4 book ai didi

pthread_cond_signal 可以唤醒多个线程吗?

转载 作者:行者123 更新时间:2023-12-03 12:58:57 33 4
gpt4 key购买 nike

我正在研究 Pthread 的条件变量。当我阅读 pthread_cond_signal 的解释时,我看到以下内容。

The pthread_cond_signal() function shall unblock at least one of the threads that are blocked on the specified condition variable cond (if any threads are blocked on cond).

直到现在我才知道 pthread_cond_signal() 一次只会唤醒一个线程。但是,引用的解释说至少一个。这是什么意思?它能唤醒一个以上的线程吗?如果有,为什么会有pthread_cond_broadcast()


En passant,我希望以下代码取自UNIX Systems Programming book of Robbins也和我的问题有关。作者在 waitbarrier 函数中使用 pthread_cond_broadcast() 而不是 pthread_cond_signal() 有什么原因吗? 作为次要的一点,为什么 !berror 也需要检查作为谓词的一部分? 当我通过更改尝试这两个时,我看不出任何区别。

/*

The program implements a thread-safe barrier by using condition variables. The limit
variable specifies how many threads must arrive at the barrier (execute the
waitbarrier) before the threads are released from the barrier.
The count variable specifies how many threads are currently waiting at the barrier.
Both variables are declared with the static attribute to force access through
initbarrier and waitbarrier. If successful, the initbarrier and waitbarrier
functions return 0. If unsuccessful, these functions return a nonzero error code.

*/

#include <errno.h>
#include <pthread.h>
#include <stdio.h>

static pthread_cond_t bcond = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t bmutex = PTHREAD_MUTEX_INITIALIZER;
static int count = 0;
static int limit = 0;

int initbarrier(int n) { /* initialize the barrier to be size n */
int error;

if (error = pthread_mutex_lock(&bmutex)) /* couldn't lock, give up */
return error;
if (limit != 0) { /* barrier can only be initialized once */
pthread_mutex_unlock(&bmutex);
return EINVAL;
}
limit = n;
return pthread_mutex_unlock(&bmutex);
}

int waitbarrier(void) { /* wait at the barrier until all n threads arrive */
int berror = 0;
int error;

if (error = pthread_mutex_lock(&bmutex)) /* couldn't lock, give up */
return error;
if (limit <= 0) { /* make sure barrier initialized */
pthread_mutex_unlock(&bmutex);
return EINVAL;
}
count++;
while ((count < limit) && !berror)
berror = pthread_cond_wait(&bcond, &bmutex);
if (!berror) {
fprintf(stderr,"soner %d\n",
(int)pthread_self());
berror = pthread_cond_broadcast(&bcond); /* wake up everyone */
}
error = pthread_mutex_unlock(&bmutex);
if (berror)
return berror;
return error;
}

/* ARGSUSED */
static void *printthread(void *arg) {
fprintf(stderr,"This is the first print of thread %d\n",
(int)pthread_self());
waitbarrier();
fprintf(stderr,"This is the second print of thread %d\n",
(int)pthread_self());
return NULL;
}

int main(void) {
pthread_t t0,t1,t2;

if (initbarrier(3)) {
fprintf(stderr,"Error initilizing barrier\n");
return 1;
}
if (pthread_create(&t0,NULL,printthread,NULL))
fprintf(stderr,"Error creating thread 0.\n");
if (pthread_create(&t1,NULL,printthread,NULL))
fprintf(stderr,"Error creating thread 1.\n");
if (pthread_create(&t2,NULL,printthread,NULL))
fprintf(stderr,"Error creating thread 2.\n");
if (pthread_join(t0,NULL))
fprintf(stderr,"Error joining thread 0.\n");
if (pthread_join(t1,NULL))
fprintf(stderr,"Error joining thread 1.\n");
if (pthread_join(t2,NULL))
fprintf(stderr,"Error joining thread 2.\n");
fprintf(stderr,"All threads complete.\n");
return 0;
}

最佳答案

由于spurious wake-ups pthread_cond_signal 可以唤醒多个线程。

pthread_cond_wait.c 中查找单词“spurious”来自 glibc。


waitbarrier 中,它必须在所有线程都到达该点时唤醒所有线程,因此它使用 pthread_cond_broadcast

关于pthread_cond_signal 可以唤醒多个线程吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55935188/

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