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

本文详细介绍了如何使用POSIX标准中的Pthreads API来创建生产者消费者线程模型。通过互斥锁和信号量机制实现线程间的同步与互斥,展示了如何在缓冲区中添加和移除产品,以及如何控制生产者和消费者的执行顺序。示例代码演示了在不同生产者和消费者数量下的运行效果。
摘要由CSDN通过智能技术生成

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

...

...

可以使用 Python 的 threading 模块以及 queue 模块来实现生产者消费者问题信号量解决方案。具体实现可以参考以下代码示例: ```python import threading import queue MAX_SIZE = 10 queue = queue.Queue(MAX_SIZE) # producer and consumer semaphores prod_sem = threading.Semaphore(MAX_SIZE) cons_sem = threading.Semaphore(0) class Producer(threading.Thread): def run(self): while True: # acquire producer semaphore prod_sem.acquire() item = produce_item() # add item to queue queue.put(item) print(f"Produced item: {item}") # release consumer semaphore cons_sem.release() class Consumer(threading.Thread): def run(self): while True: # acquire consumer semaphore cons_sem.acquire() item = queue.get() consume_item(item) print(f"Consumed item: {item}") # release producer semaphore prod_sem.release() # helper functions def produce_item(): # create item here return item def consume_item(item): # consume item here pass # start producer and consumer threads Producer().start() Consumer().start() ``` 该示例使用 Python 的多线程实现生产者消费者问题信号量解决方案。生产者线程在生产一个新的商品时获取生产者信号量,将商品添加到队列中,并释放消费者信号量,表示队列中有新商品可以被消费者线程获取。消费者线程在获取新商品时获取消费者信号量,从队列中获取商品并进行消费,然后释放生产者线程信号量,表示队列中有新空间可以被生产者线程使用。这样可以保证生产者和消费者线程不会重复使用已经被生产或消费的商品或队列空间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值