使用POSIX标准中的Pthreads API来创建多个生产者、消费者线程
定义线程:pthread_t tid
创建线程:pthread_create(&tid,&attr,runner,argv[1]);
join线程:pthread_join(tid,NULL);
使用PthreadsAPI的信号量机制互斥与同步
定义信号量:sem_t sem
初始化信号量:sem_init(&sem, 0, n);
P操作:sem_wait(&sem);
V操作:sem_post(&sem);
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#define BUFF_SIZE 5 // 定义缓冲区buffer大小为5
int buffer[BUFF_SIZE]; // 用循环队列模拟缓冲区
int in = 0; // 产品进缓冲区时的缓冲区下标
int out = 0; // 产品出缓冲区时的缓冲区下标
int productID = 0; // 产品号
int consumeID = 0; // 将被消耗的产品号
sem_t s; // 定义互斥信号量, 互斥锁s
sem_t n; // 定义同步信号量n, buffer中已放入的产品个数
sem_t e; // 定义同步信号量e, buffer中空单元个数
// 生产一个产品, 输出新产品的ID号
void produce()
{
printf("成功生产了第:%d个产品\n",++productID);
}
// 把新生产的产品放入buffer
void appen()
{
printf("将新生产的产品放入缓冲区\n");
buffer[in] = productID;
in = (in+1)%BUFF_SIZE;
int i;
// 输出缓冲区当前的状态
for(i = 0; i<BUFF_SIZE; i++)
{
printf("i : %d",buffer[i]);
if(i == in) printf("<-生产");
if(i == out) printf("<-消费");
printf("\n");
}
printf("\n");
}
// 生产者
void * Producer()
{
while(1)
{
sem_wait(&e); // 生产者首先试图拿一个buffer空单元, 获取一个空单元
sem_wait(&s); // 获取互斥锁s, 对临界区加锁, 互斥访问临界区buffer
produce(); // 生产一个产品
appen(); // 把新生产的产品放入buffer
Sleep(1000); // 模拟实际生产, 耗时1S
sem_post(&s); // 临界区buffer访问完毕, 释放互斥锁s
sem_post(&n); // 生产者任务完成, 释放一个产品
}
}
// 从buffer中取出一个产品
void take()
{
printf("从缓冲区中取出第:%d个产品\n",++consumeID);
consumeID = buffer[out];
out = (out+1)%BUFF_SIZE;
int i;
// 输出缓冲区当前的状态
for(i = 0; i<BUFF_SIZE; i++)
{
printf("i : %d",buffer[i]);
if(i == in) printf("<-生产");
if(i == out) printf("<-消费");
printf("\n");
}
}
// 消耗一个产品
void consume()
{
printf("消费了%d个产品\n\n",consumeID);
}
// 消费者
void * Consumer()
{
while(1)
{
sem_wait(&n); // 消费者首先试图拿一个buffer产品,获取一个产品
sem_wait(&s); // 获取互斥锁s,对临界区加锁,互斥访问临界区buffer
take(); // 从buffer中取出一个产品
consume(); // 消耗一个产品
Sleep(1000); // 模拟实际消费,耗时1S
sem_post(&s); // 临界区buffer访问完毕,释放互斥锁s
sem_post(&e); // 生产者任务完成,释放一个buffer空单元
}
}
int main()
{
// 调整下面的数值,可以发现,当生产者个数多于消费者个数时,
// 生产速度快,生产者经常等待消费者;反之,消费者经常等待
// 生产者的个数
int P_COUNT = 2;
// 消费者的个数
int C_COUNT = 1;
pthread_t p[P_COUNT],c[C_COUNT];
// 创建各个信号
sem_init(&s,0,1); // 初始化信号量s为互斥锁
sem_init(&n,0,0); // 初始化信号量n:buffer中已放入的产品数目(初始为0)
sem_init(&e,0,BUFF_SIZE); // 初始化buffer中单元数目为BUFF_SIZE
int i = 0;
// 创建生产者线程
for(i = 0; i < P_COUNT; i++)
{
pthread_create(&p[i],NULL,Producer,NULL);
pthread_create(&c[i],NULL,Consumer,NULL);
}
// 创建消费者线程
for(i = 0; i < C_COUNT; i++)
{
pthread_join(p[i],NULL);
pthread_join(c[i],NULL);
}
}
Console输出:
成功生产了第:1个产品
将新生产的产品放入缓冲区
i : 1<-消费
i : 0<-生产
i : 0
i : 0
i : 0
成功生产了第:2个产品
将新生产的产品放入缓冲区
i : 1<-消费
i : 2
i : 0<-生产
i : 0
i : 0
成功生产了第:3个产品
将新生产的产品放入缓冲区
i : 1<-消费
i : 2
i : 3
i : 0<-生产
i : 0
从缓冲区中取出第:1个产品
i : 1
i : 2<-消费
i : 3
i : 0<-生产
i : 0
消费了1个产品
从缓冲区中取出第:2个产品
i : 1
i : 2
i : 3<-消费
i : 0<-生产
i : 0
消费了2个产品
成功生产了第:4个产品
将新生产的产品放入缓冲区
i : 1
i : 2
i : 3<-消费
i : 4
i : 0<-生产
成功生产了第:5个产品
将新生产的产品放入缓冲区
i : 1<-生产
i : 2
i : 3<-消费
i : 4
i : 5
...
...
来源:oschina
链接:https://my.oschina.net/u/2503731/blog/661391