首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在c中使用条件变量

在c中使用条件变量
EN

Stack Overflow用户
提问于 2021-09-18 16:33:56
回答 1查看 173关注 0票数 0

我有一个用c++编写的多线程程序,它有3个线程、主线程、生产者线程和使用者线程。代码使用条件变量来处理信令和处理发出的信号。问题是,当我运行程序时,似乎有些发出的信号丢失了,没有被任何处理程序捕获。有人能给我解释一下这些输出吗?

全球变量:

代码语言:javascript
复制
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

int avail = 0;

生产者线:

代码语言:javascript
复制
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);
}

消费者线索:

代码语言:javascript
复制
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);
    }
}

主螺纹:

代码语言:javascript
复制
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);
}

样本输出:

代码语言:javascript
复制
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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-19 14:39:25

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

如果您想在生产之后强制消费,您应该让生产者检查是否已经使用了avail-able东西,例如编写如下循环:

代码语言:javascript
复制
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);
}
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69236549

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档