在c中使用条件变量

using condition variable in c

我有一个用 c 编写的多线程程序,它有 3 个线程,主线程,生产者线程和消费者线程。该代码使用条件变量来处理信号和处理发出的信号。问题是当我 运行 程序似乎有些发出的信号丢失并且没有被任何处理程序捕获。有人可以向我解释这些输出吗?

全局变量:

static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

int avail = 0;

生产者线程:

static void *producer_thread(void *arg)
{   
    for (size_t i = 0; i < 10; i++)
    {
        pthread_mutex_lock(&mtx);
        avail = 1;
    //    sleep(2);

        
        pthread_mutex_unlock(&mtx);

        pthread_cond_broadcast(&cond);

        printf("sent signal#%ld from signaling thread\n", i);
    }
    
    pthread_exit(NULL);
}

消费者线程:

static void *consumer_thread(void *arg)
{
    while (1)
    {
        pthread_mutex_lock(&mtx);
        
        while(0 == avail)
        {
            pthread_cond_wait(&cond, &mtx);
        }

        printf("received signal from consuming_thread\n");
        avail = 0;
        pthread_mutex_unlock(&mtx);
    }
}

主线程:

int main(int argc, char *argv[])
{
    pthread_t tid1, tid2;
    int rc;

    rc = pthread_create(&tid1, NULL, consumer_thread, NULL);
    if(rc){
        printf("error in pthread_create form consuming_thread\n");
        exit(-1);
    }

    rc = pthread_create(&tid2, NULL, producer_thread, NULL);
    if(rc){
        printf("error in pthread_create form signalling thread\n");
        exit(-1);
    }

    pthread_exit(NULL);
}

示例输出:

sent signal#0 from signaling thread
received signal from consuming_thread
sent signal#1 from signaling thread
sent signal#2 from signaling thread
sent signal#3 from signaling thread
sent signal#4 from signaling thread
sent signal#5 from signaling thread
sent signal#6 from signaling thread
sent signal#7 from signaling thread
sent signal#8 from signaling thread
received signal from consuming_thread
sent signal#9 from signaling thread
received signal from consuming_thread

一个问题是您的生产者线程在将 avail 设置为 1 之前不验证它是否为零。当条件广播时,不能保证等待的消费者线程立即甚至首先得到调度。当它被调度时,它仍然必须首先锁定它在开始等待时放弃的互斥量。生产者的循环完全有可能在此之前运行几次。

如果你想在生产后强制消费,你应该让生产者检查 avail-able 的东西是否已经被消费,对于 example 通过写你的循环如下:

for (size_t i = 0; i < 10; i++)
{    
    int proceed = 0;
    while (!proceed) {
        pthread_mutex_lock(&mtx);
        if (avail == 0) {
            avail = 1;
            proceed = 1;
        }
        pthread_mutex_unlock(&mtx);
    }
    pthread_cond_broadcast(&cond);
    printf("sent signal#%ld from signaling thread\n", i);
}