生产者-消费者正确实施

发布于 2024-12-12 04:00:58 字数 991 浏览 4 评论 0原文

我正在尝试实现生产者-消费者模型,但遇到了一些问题。考虑代码

int number=0;

void* master(void* p){
    int i;
    pthread_t workers[5];
    for(i=0;i<5;i++)
        pthread_create(&workers[i],NULL,worker,NULL);

    while(1){
        //possible delay

        pthread_mutex_lock(&mutex);
        if(number == LIMIT)
            pthread_cond_wait(&not_full,&mutex);

        number++;
        pthread_cond_signal(&not_empty);
        pthread_mutex_unlock(&mutex);
    }
}

void* worker(void* p){
    while(1){
        pthread_mutex_lock(&mutex);
        if(number == 0)
            pthread_cond_wait(&not_empty,&mutex);

        number--;
        pthread_cond_signal(&not_full);
        pthread_mutex_unlock(&mutex);

        //possible delay
    }
}

也许这对你来说是显而易见的,但我无法弄清楚变量号 get 是负数怎么可能,这当然会让工作线程进一步减少它。我做错了什么?

--编辑--

好吧,一个进展是执行 while(number==0) 而不是 if,但我仍然不明白怎么可能有两个线程在获取后递减变量not_empty 信号,当它小于 2 时。

I'm trying to implement producer-consumer model and I got some problem with it. Consider code

int number=0;

void* master(void* p){
    int i;
    pthread_t workers[5];
    for(i=0;i<5;i++)
        pthread_create(&workers[i],NULL,worker,NULL);

    while(1){
        //possible delay

        pthread_mutex_lock(&mutex);
        if(number == LIMIT)
            pthread_cond_wait(¬_full,&mutex);

        number++;
        pthread_cond_signal(¬_empty);
        pthread_mutex_unlock(&mutex);
    }
}

void* worker(void* p){
    while(1){
        pthread_mutex_lock(&mutex);
        if(number == 0)
            pthread_cond_wait(¬_empty,&mutex);

        number--;
        pthread_cond_signal(¬_full);
        pthread_mutex_unlock(&mutex);

        //possible delay
    }
}

Maybe it's obvious to you, but I can't figure out how is it possible that the variable number get's negative which of course lets the worker thread decrement it further. What am I doing wrong?

--EDIT--

Ok one progress is doing while(number==0) instead of if, yet I still don't understand how could it happen that there could be two threads decrementing the variable after getting the not_empty signal while it is less then two.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

比忠 2024-12-19 04:00:58

我认为用 while 替换 if 可能会掩盖问题而不是解决问题。 Per 为什么 pthread 的条件变量函数需要互斥锁? 与条件变量一起使用的互斥体用于保护对该条件变量的访问。在您的情况下,您似乎使用 mutex 来保护三件事:全局 number 和两个条件变量 not_fullnot_empty

您需要意识到的事情 - pthread_cond_wait() 的实现将解锁您的互斥体,并在返回之前重新锁定它,并且这个打开的窗口允许其他线程在您不希望它们进入时进入。将 if 替换为 while 是一种解决方案,但另一种解决方案是在工作线程中使用第二个互斥体来保护对“数字”以及条件等待的访问。

I think replacing if with while may be masking a problem rather than solving it. Per Why do pthreads’ condition variable functions require a mutex? the mutex you use with a condition variable is used to protect access to that condition variable. In your case you appear to be using mutex to protect three things: the global number, and two condition variables, not_full and not_empty.

Something you need to realize -- the implementation of pthread_cond_wait() will unlock your mutex, and re-locked it before it returns, and this window of being open is allowing for other threads to get in when you don't want them to. Replacing if with while as you have is one solution, but another is using a second mutex in your worker to protect access to both "number" as well as the conditioned wait.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文