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

关于经典生成者和消费者问题

    来源: 互联网  发布时间:2017-01-04

    本文导语:  #include     #include     #define BUFFER_SIZE 16 // 缓冲区数量    // 缓冲区相关数据结构    struct prodcons    {    int buffer[BUFFER_SIZE]; /* 实际数据存放的数组*/    int readpos; /* 读写指针*/   int writepos;   pthread_mutex_...

#include    
#include    
#define BUFFER_SIZE 16 // 缓冲区数量   
// 缓冲区相关数据结构   

struct prodcons   
{   
int buffer[BUFFER_SIZE]; /* 实际数据存放的数组*/   
int readpos; /* 读写指针*/  
int writepos;  
pthread_mutex_t lock; /* 互斥体lock 用于对缓冲区的互斥操作 */  
pthread_cond_t notempty; /* 缓冲区非空的条件变量 */ 
pthread_cond_t notfull; /* 缓冲区未满的条件变量 */  
}; 


//初始化缓冲区结构  
void init(struct prodcons *b)  
{  
pthread_mutex_init(&b->lock, NULL);  
pthread_cond_init(&b->notempty, NULL);  
pthread_cond_init(&b->notfull, NULL);  
b->readpos = 0;  
b->writepos = 0;  
}  

/* 将产品放入缓冲区,这里是存入一个整数*/  
void put(struct prodcons *b, int data)  
{  
pthread_mutex_lock(&b->lock); 
/* 等待缓冲区未满*/  
if ((b->writepos + 1) %  BUFFER_SIZE == b->readpos)  
pthread_cond_wait(&b->notfull, &b->lock);  
/* 写数据,并移动指针 */ 
b->buffer[b->writepos] = data; 
b->writepos++;  
if (b->writepos >= BUFFER_SIZE)  
b->writepos = 0;  
/* 设置缓冲区非空的条件变量*/  
pthread_cond_signal(&b->notempty);  
pthread_mutex_unlock(&b->lock);  
}   

/* 从缓冲区中取出整数*/  
int get(struct prodcons *b)  
{  
int data;  
pthread_mutex_lock(&b->lock); 
/* 等待缓冲区非空*/ 
if (b->writepos == b->readpos) 
pthread_cond_wait(&b->notempty, &b->lock);  
/* 读数据,移动读指针*/  
data = b->buffer[b->readpos]; 
b->readpos++;  
if (b->readpos > = BUFFER_SIZE)  
b->readpos = 0;  
/* 设置缓冲区未满的条件变量*/ 
pthread_cond_signal(&b->notfull); 
pthread_mutex_unlock(&b->lock);  
return data;  
}  

/* 测试:生产者线程将1 到10000 的整数送入缓冲区, 消费者线程从缓冲区中获取整数,两者都打印信息*/  

#define OVER ( - 1)  
struct prodcons buffer;  
void *producer(void *data)  
{  
int n;  
for (n = 0; n lock);  此时put、get函数都应该是竞争状态(即大家都pthread_mutex_lock(&b->lock); )  应该未必是get函数能拿到,如果是put再次拿到mutex 不是一直是put函数在运行么,更有甚者put函数把缓存都写满从头又开始写??
2、假设我在put函数中最后2行加入 sleep 10多秒  ,然后放开锁,如果锁被get函数拿到,那么get中的pthread_cond_wait(&b->notempty, &b->lock);  还能获得信号,再放开锁么?

|
首先这段代码的实现思路确实是有问题的,楼主说的第1点情况确实是有可能发生。
还有对于条件变量的使用,这里说一下:

if (b->writepos == b->readpos)
    pthread_cond_wait(&b->notempty, &b->lock);

一般是用while来代替if也就是改为:

while (b->writepos == b->readpos)
    pthread_cond_wait(&b->notempty, &b->lock);

既然你已将条件变量更改的“消息”传递了出去,但你put所属的生产者锁还没释放的话,
消费者会再等待啊,等你把锁释放了,它才从条件变量返回继续执行。

|


if改为while是必须的,估计是楼主笔误。

    
 
 
 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • j2ee架构最经典的例子是什么?petstore算是最经典的例子吗?
  • 请大家推荐几个经典的JAVA网站!!(经典者给分)
  • THING IN JAVA 第二版(中文版) 已经出炉了!!(经典的不能再经典了)
  • 经典board游戏 Domination
  • linux有没有像--《windows程序设计》一样经典的书籍
  • 在Linux下开发有哪些经典的书籍值得看
  • 大家帮推荐本 linux下多线程编程 的经典书吧 多谢
  • 求unix经典书籍
  • 求LINUX经典书籍
  • 谁知道经典的DOS游戏去哪里下载?
  • Wii经典街机iPhone移植版 SpaceBubble
  • java中最经典的书是什么
  • 大家能否推荐几个学习java的经典例子?
  • 请前辈介绍一本jsp+数据库的经典好书!!!
  • 请你推荐一本给初学者的jsp经典好书!!!
  • mysql iis7站长之家
  • 我想系统的学习LINUX,有一订的计算机基础。可以推荐一本经典教材吗?
  • 请教学习c++有那些经典书籍?
  • 请各位大侠推荐两本Solaris的经典书籍?
  • <自己写操作系统>这本书电子版那位有啊?据说很经典的


  • 站内导航:


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

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

    浙ICP备11055608号-3