前言:
此刻同学们对“python 消费者生产者 多线程 环形队列”大约比较珍视,大家都需要了解一些“python 消费者生产者 多线程 环形队列”的相关内容。那么小编同时在网摘上网罗了一些有关“python 消费者生产者 多线程 环形队列””的相关知识,希望兄弟们能喜欢,你们快快来学习一下吧!1. 生产者消费者模型
从现实生活中的角度出发,对于这个模型,我们可以总结为3 2 1原则,即:
三种关系:
生产者与生产者:互斥关系,我生产的时候你不能生产
消费者与消费者:互斥关系,我消费的时候你不能消费
生产者与消费者:同步关系,我生产了你才能消费,我消费完了你才能生产
两个角色
生产者
消费者
一个中间媒介
生产出来的产品
2. 使用规范
在这里是基于多线程的生产者消费者模型,势必会出现多个线程同时生产,多个线程同时消费,生产者没有生产完,消费者就去消费等的情况,此时为了解决这些问题,我们引入互斥量、条件变量、信号量等概念;并且在使用时遵循以下的规则:
3. 信号量
关于互斥锁和条件变量在这里不详细介绍,今天主要用到信号量,前面进程间通信时也用到过进程间通信—信号量,进程间的信是以集合的形式出现,而这里我们实现线程间的互斥所用的信号量是以个数的形式出现,而且实现要比进程间通信的信号量简单的多。
4. 函数接口
sem_init———-初始化信号量
#include <semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned int value);
//参数:
//1.sem:表示你要初始化的信号量
//2.pshared:0表示线程间共享,非0表示进程间共享
//3.value:信号量的初始值
sem_destory———销毁信号量
#include <semaphore.h>
int sem_destroy(sem_t *sem);
//参数:创建的信号量
sem_wait———–等待信号量(p操作)
#include <semaphore.h>
int sem_post(sem_t *sem);
//p操作,将信号量值减一,相当于减资源
sem_post———-发布信号量(V操作)
#include <semaphore.h>
int sem_wait(sem_t *sem);
//v操作,表示使用完资源了,可以将其归还
5. 基于环形队列的生产者消费者模型
5.1 思路:
队列一般是用链表来实现,但是链表存储不是连续的,在这里使用数组实现环形队列,长度为n
对于生产者,实际操作的是数组中空位置的个数,范围是:n—->0
对于消费者,实际操作的是数组中数据的个数,范围是:0—–>n
当生产者和消费者指向同一个位置,就可能出现死锁的问题,故此我们遵循3个原则
生产者要先与消费者
当环形队列为空,必须保证生产者先运行(为空或则满由计数器决定)
当环形队列为满时,必须保证消费者先运行
代码:
#include <stdio.h>
#include <unistd.h>
#include <semaphore.h>
#include <pthread.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#define N 64
int buff[N];//环形队列
sem_t blanks;//生产者
sem_t datas;//消费者
pthread_mutex_t mutex;//实现互斥
void* procduct(void* arg)
{
int i = 0;
while(1){
printf("Procduct start pocduct\n");
sem_wait(&blanks);//拿走一个资源
pthread_mutex_lock(&mutex);//一次只允许一个生产者
int data = rand()%2048;
buff[i] = data;
printf("pocuduct data is: %d\n",data);
++i;
i = i%N;
pthread_mutex_unlock(&mutex);//生产完毕,解锁,让其他生产者进行生产
sem_post(&datas);//生产完毕,数据个数加1
sleep(1);
}
}
void* consumer(void* arg)
{
int i = 0;
while(1){
printf("consumer start consum\n");
sem_wait(&datas);
pthread_mutex_lock(&mutex);//保证一个消费者进行消费
int data = buff[i];
printf("consumer data is: %d\n",data);
++i;
i = i%N;
sem_post(&blanks);
pthread_mutex_unlock(&mutex);
//sleep(1);
}
}
int main()
{
srand(time(0));
//初始化信号量
sem_init(&blanks, 0, N);//生产者的信号量,n--> 0
sem_init(&datas, 0, 0);//消费者的信号量,0---> n
pthread_mutex_init(&mutex, NULL);//互斥锁的出初始化
//创建两个生产者,两个消费者
pthread_t pid1,pid2;//生产者
pthread_t cid1,cid2;//消费者
pthread_create(&pid1, NULL, procduct, NULL);
pthread_create(&pid2, NULL, procduct, NULL);
pthread_create(&cid1, NULL, consumer, NULL);
pthread_create(&cid1, NULL, consumer, NULL);
sem_destroy(&blanks);
sem_destroy(&datas);
pthread_mutex_destroy(&mutex);
pthread_join(pid1,NULL);
pthread_join(pid2,NULL);
pthread_join(cid1,NULL);
pthread_join(cid2,NULL);
return 0;
}
结果:
更多linux免费视频资料获取 后台私信【架构】