生产者消费者python信号量_用信号量机制解决生产者消费者问题

使用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 

#include 

#include 

#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

{

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

{

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 

{

pthread_create(&p[i],NULL,Producer,NULL);

pthread_create(&c[i],NULL,Consumer,NULL);

}

// 创建消费者线程

for(i = 0; 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

...

...

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值