pthread_cond_signal 可以唤醒多个线程吗?

标签 c multithreading pthreads condition-variable

我正在研究 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/

相关文章:

Java PrintStream 重定向行为异常

c - 使用 pthread 读取文件并执行操作

android - swprintf() 不适用于 Android Kitkat 及以下版本?

c - 在 VSCode 中查看 C 文档?

C++ 多线程优化

c++ - 为什么不同的CPU对执行相同的代码需要不同的时间

c - 奇怪的 C 程序行为

c - pthread_rwlock的优先级?

使用 getc() 和 putc() 在 C 中复制文件文本 - 输出文件中的二进制代码

c - 在 Linux 上执行进程之前获取 pid