多线程间的同步-经典的生产者与消费者代码

来源:互联网 发布:tinycore linux有啥用 编辑:程序博客网 时间:2024/06/06 03:58

#include <stdio.h>

#include <pthread.h>

#define BUFFER_SIZE 16 // 缓冲区数量

 

 

/* 下面以经典的生产者/消费者问题为例来阐述Linux线程的控制和通信。

一组生产者线程与一组消费者线程通过缓冲区发生联系。生产者线程将生产的产品送入缓冲区,

消费者线程则从中取出产品。缓冲区有N 个,是一个环形的缓冲池。*/

struct prodcons

{

         // 缓冲区相关数据结构

         int buffer[BUFFER_SIZE]; /* 实际数据存放的数组*/

         pthread_mutex_t lock; /* 互斥体lock 用于对缓冲区的互斥操作 */

         int readpos, writepos; /* 读写指针*/

         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);

         /* (如果写的速度比较快)等待缓冲区未满 //表示写到了没读到的那个byte了*/

         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 到2000 的整数送入缓冲区,消费者线

程从缓冲区中获取整数,两者都打印信息*/

#define OVER ( - 1)

struct prodcons buffer;

void *producer(void *data)

{

         int n;

         for (n = 0; n < 2000; n++)

         {

                   printf("%d --->\n", n);

                   //sleep(1);

                   put(&buffer, n);

         }

         put(&buffer, OVER);

         return NULL;

}

 

void *consumer(void *data)

{

         int d;

         while (1)

         {

                   d = get(&buffer);

                   if (d == OVER)

                     break;

                   printf("--->%d \n", d);

         }

         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);

         /* 等待两个线程结束*/

         pthread_join(th_a, &retval);

         pthread_join(th_b, &retval);

         printf("main pthread exit....\n");

         return 0;

}

原创粉丝点击