Chinaunix首页 | 论坛 | 博客
  • 博客访问: 55556
  • 博文数量: 12
  • 博客积分: 207
  • 博客等级: 入伍新兵
  • 技术积分: 115
  • 用 户 组: 普通用户
  • 注册时间: 2012-10-25 11:00
文章分类
文章存档

2013年(4)

2012年(8)

分类: LINUX

2012-10-31 18:38:44

 多线程生产者消费者.rar  

/*程序主要部分说明:
生产者线程不断顺序地将0~1000个数字写入共享的循环缓冲区,同时消费者线程不断从共享的缓冲区读取数据;生产者和消费者只能有一个在临界区,如果一个线程在临界区操作另一个线程只能阻塞等待,直到被唤醒;主要的函数创建线程函数:pthread_create(&th_a, NULL, producer, 0)等待指定的线程结束函数:pthread_join(th_a, &retval); pthread_cond_wait(&b->notfull, &b->lock);  线程挂起等待直到缓冲区不满释放锁;生产者进行生产;        pthread_cond_wait(&b->notempty, &b->lock); 线程挂起等待直到缓冲区不空释放锁消费者读取数据;
pthread_cond_signal(&b->notempty);  /唤醒等待在b->notempty条件变量上的消费者线程上锁;
pthread_cond_signal(&b->notfull);  //若缓冲区不满,则唤醒b->notfull条件变量上的生产者线程上锁;*/

 
 
#include
#include
#include
#include "pthread.h"
 
#define BUFFER_SIZE 16
 
/* Circular buffer of integers. */
struct prodcons {
  int buffer[BUFFER_SIZE];      /* the actual data */  //定义数据缓冲区;
 
  pthread_mutex_t lock;         /* mutex ensuring exclusive access to buffer */ //定义锁;
  int readpos, writepos;        /* positions for reading and writing */ //定义读,写变量
  pthread_cond_t notempty;      /* signaled when buffer is not empty */ //定义不空时的信号;
  pthread_cond_t notfull;       /* signaled when buffer is not full */   //定义空时的信号;
};
 
/*--------------------------------------------------------*/
/* Initialize a buffer */
void init(struct prodcons * b)
{
  pthread_mutex_init(&b->lock, NULL);    //初始化锁;
  pthread_cond_init(&b->notempty, NULL); //初始化b->notempty条件变量;
  pthread_cond_init(&b->notfull, NULL);  //初始化b->notfull条件变量; 
  b->readpos = 0;         //初始化读写位置;
  b->writepos = 0;
}
/*--------------------------------------------------------*/
/* Store an integer in the buffer */
void put(struct prodcons * b, int data)  //生产者写入共享循环缓冲区的函数; 
{
    pthread_mutex_lock(&b->lock);   //上锁;
 
      /* Wait until buffer is not full */
     while ((b->writepos + 1) % BUFFER_SIZE == b->readpos) {  //判断读写位置,writepos + 1为了防止两个进程同时阻塞等待;
        printf("wait for not full\n");
        pthread_cond_wait(&b->notfull, &b->lock);   //线程挂起等待直到缓冲区不满释放锁;;
      }
  /* Write the data and advance write pointer */
      b->buffer[b->writepos] = data; //写数据;
      b->writepos++;           //写的位置加1;
      if (b->writepos >= BUFFER_SIZE) b->writepos = 0; //如果写的位置大于缓冲区的长度,则把写的指针置0 
  /* Signal that the buffer is now not empty */
      pthread_cond_signal(&b->notempty);  //唤醒等待在b->notempty条件变量上的消费者线程上锁;
 
    pthread_mutex_unlock(&b->lock); //解锁;
}
/*--------------------------------------------------------*/
/* Read and remove an integer from the buffer */
int get(struct prodcons * b)  //消费者读取共享循环缓冲区的函数;
{
      int data;
    pthread_mutex_lock(&b->lock); //上锁,成功返回0;
 
     /* Wait until buffer is not empty */
      while (b->writepos == b->readpos) {  //判断读写位置是否相等; 
        printf("wait for not empty\n");     
        pthread_cond_wait(&b->notempty, &b->lock); //线程挂起等待直到缓冲区不空释放锁; 
      }
      /* Read the data and advance read pointer */
      data = b->buffer[b->readpos]; //读数据;
      b->readpos++;   //读的位置加1;
      if (b->readpos >= BUFFER_SIZE) b->readpos = 0; //如果读的位置大于缓冲区的长度,则把读的指针置0; 
      /* Signal that the buffer is now not full */
      pthread_cond_signal(&b->notfull);  //若缓冲区不满,则唤醒b->notfull条件变量上的生产者线程上锁;
 
      pthread_mutex_unlock(&b->lock);  //解锁;
      return data;
}
/*--------------------------------------------------------*/
#define OVER (-1)
struct prodcons buffer;
/*--------------------------------------------------------*/
void * producer(void * data)   //生产者函数;
{
      int n;
      for (n = 0; n < 1000; n++) {  //初始化buffer,共有1000个产品;
        printf(" put-->%d\n", n);
        put(&buffer, n);    //将产品放入共享区;
    }
  put(&buffer, OVER);  //over 结束标志;
  printf("producer stopped!\n");
  return NULL;
}
/*--------------------------------------------------------*/
void * consumer(void * data) //消费者函数;
{
  int d;
  while (1) {
    d = get(&buffer);         //从共享数据区读取数据到变量d;
    if (d == OVER ) break;    //判断d是否是over;
    printf("              %d-->get\n", d); //打印缓冲区的值;
  }
  printf("consumer stopped!\n"); 
  return NULL;
}
/*--------------------------------------------------------*/
int main(void)
{
      pthread_t th_a, th_b;  //定义线程号;
      void * retval;        //定义返回值;
 
      init(&buffer);       //初始化共享缓冲区;
     pthread_create(&th_a, NULL, producer, 0); //创建生产者线程;
      pthread_create(&th_b, NULL, consumer, 0); //创建消费者线程;
  /* Wait until producer and consumer finish. */
      pthread_join(th_a, &retval);   //主线程以阻塞的方式等待th_a指定的线程结束。当函数返回时,被等待线程的资源被收回。如果进程已经结束,那么该函数会立即返回
      pthread_join(th_b, &retval);   //主线程以阻塞的方式等待th_b指定的线程结束;
 
      return 0;
}

阅读(1274) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~