当前位置:  技术问答>linux和unix

关于生产者-消费者的程序

    来源: 互联网  发布时间:2016-10-19

    本文导语:  代码如下 #include  #include  #include  struct msg { struct msg *next; int num; }; struct msg *head; pthread_cond_t has_product = PTHREAD_COND_INITIALIZER; pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; void *consumer(void *p) { struct msg *mp; for (...

代码如下
#include 
#include 
#include 

struct msg {
struct msg *next;
int num;
};

struct msg *head;
pthread_cond_t has_product = PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

void *consumer(void *p)
{
struct msg *mp;

for (;;) {
pthread_mutex_lock(&lock);
while (head == NULL)
pthread_cond_wait(&has_product, &lock);
mp = head;
head = mp->next;
pthread_mutex_unlock(&lock);
printf("Consume %dn", mp->num);
free(mp);
sleep(rand() % 5);
}
}

void *producer(void *p)
{
struct msg *mp;
for (;;) {
mp = malloc(sizeof(struct msg));
mp->num = rand() % 1000 + 1;
printf("Produce %dn", mp->num);
pthread_mutex_lock(&lock);
mp->next = head;
head = mp;
pthread_mutex_unlock(&lock);
pthread_cond_signal(&has_product);
sleep(rand() % 5);
}
}

int main(int argc, char *argv[]) 
{
pthread_t pid, cid;  

srand(time(NULL));
pthread_create(&pid, NULL, producer, NULL);
pthread_create(&cid, NULL, consumer, NULL);
pthread_join(pid, NULL);
pthread_join(cid, NULL);
return 0;
}

|
我也是觉得没有区别

|
有区别的!!!
为什么要使用while循环来判断条件,是因为可能有“惊群效应”。

引用下POSIX的RATIONALE: 

Condition Wait Semantics 

It is important to note that when pthread_cond_wait() and pthread_cond_timedwait() return without error, the associated predicate may still be false. Similarly, when pthread_cond_timedwait() returns with the timeout error, the associated predicate may be true due to an unavoidable race between the expiration of the timeout and the predicate state change. 

The application needs to recheck the predicate on any return because it cannot be sure there is another thread waiting on the thread to handle the signal, and if there is not then the signal is lost. The burden is on the application to check the predicate. 

Some implementations, particularly on a multi-processor, may sometimes cause multiple threads to wake up when the condition variable is signaled simultaneously on different processors. 

In general, whenever a condition wait returns, the thread has to re-evaluate the predicate associated with the condition wait to determine whether it can safely proceed, should wait again, or should declare a timeout. A return from the wait does not imply that the associated predicate is either true or false. 

It is thus recommended that a condition wait be enclosed in the equivalent of a "while loop" that checks the predicate. 

从上文可以看出: 
1,pthread_cond_signal在多处理器上可能同时唤醒多个线程,当你只能让一个线程处理某个任务时,其它被唤醒的线程就需要继续 wait,while循环的意义就体现在这里了,而且规范要求pthread_cond_signal至少唤醒一个pthread_cond_wait上的线程,其实有些实现为了简单在单处理器上也会唤醒多个线程. 
2,某些应用,如线程池,pthread_cond_broadcast唤醒全部线程,但我们通常只需要一部分线程去做执行任务,所以其它的线程需要继续wait.所以强烈推荐此处使用while循环. 
   其实说白了很简单,就是pthread_cond_signal()也可能唤醒多个线程,而如果你同时只允许一个线程访问的话,就必须要使用while来进行条件判断,以保证临界区内只有一个线程在处理。


|

大多数的并发编程书籍都会强调要使用while.但是,要理解:对于2个线程,1个生产,1个消费。没有必要用while的。

问题在于,如果存在多个生产者或多个消费者。必须采用while结构。

对比while和if. while预期在pthread_cond_wait()返回后,仍然有可能再次调用pthread_cond_wait(),只要head==NULL.

而,if预期,从pthread_cond_wait()返回后,就直接继续了。

查看while,在什么时候pthread_cond_wait()还会再次被调用,那就是有另一个线程,将head置成了NULL。这一点,在2线程不会发生,但3个线程就有可能。

|

总的来说,记住用while,你就不会错。

    
 
 

您可能感兴趣的文章:

  • 生产者消费者问题...
  • linux下生产者消费者问题
  • 生产者与消费者
  • 想实现类似“生产者、消费者”问题,应该如何设置buffer?
  • 一道题目的思考-“生产者消费者问题”
  • 单个生产者线程,单个消费者线程,用 cond、mutex还是sem?
  • JAVA生产者消费者(线程同步)代码学习示例
  • 生产者消费者问题为什么不可以共用一个信号量,如果这个信号量可以设置取值固定为0到N,即当信号量取值为N的时候阻塞进程,是否也可以?
  • 300分!查错,解决多个生产者和多个消费者问题 高手进!分不够想法子再加!
  • java解决单缓冲生产者消费者问题示例
  • Lock、Condition实现简单的生产者消费者模式示例
  • 讨论一下如何实现一个生产者与两个消费者的问题(版主们一定要来看看)
  • 关于生产者与消费者问题
  • 用信号量同步生产者消费者的问题
  • 大家看看我的生产者消费者问题编程有没有问题....
  • IT科技资讯 iis7站长之家
  • 求助:有关linux下的线程编程问题-生产者消费者问题
  • 多个生产者与消费者的UNIX系统V编程实现问题
  • 深入多线程之:深入生产者、消费者队列分析
  • Linux c++ 消费者 生产者 互斥同步 问题
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • Kafka 生产者守护进程 Bruce


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3