龙空技术网

c/c++ linux 信号量--------多线程下的生产者消费者模型

Hu先生Linux后台开发 675

前言:

此刻同学们对“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免费视频资料获取 后台私信【架构】

标签: #python 消费者生产者 多线程 环形队列