进程间通信(Linux):使用多线程和信号量解决生产者/消费者问题:有一个长度为N的缓冲池被生产者和消费者共同使用。只要缓冲池未满,生产者就可以将消息送入缓冲池中;只要缓冲池不空,消费者便可从缓冲池中取走一个消息。生产者向缓冲池放入消息的同时,消费者不能操作缓冲池,反之亦然。
设计要求:
(1) 说明设置哪些信号量?信号量的含义和初始值是什么?并用信号量和P、V操作写出进程的同步与互斥算法。(注:该内容包含在设计报告的主要数据结构和流程中,属于检查内容)
(2) 查阅并自学进程、线程的创建与撤销、信号量、P操作、V操作等相关原语的系统调用。(注:该内容包含在设计报告的主要数据结构和流程中,属于检查内容)
(3)在Linux环境下,采用系统调用中的进程或线程的创建与撤销、信号量、P操作、V操作,编程解决上述问题,并完成调试与测试工作。(属于检查内容)
(4)打印:(注意:由于多个进程共享一个显示器或文件,需要互斥访问)
各线程的初始状态信息;
中间状态变化信息;
最终状态信息。
代码:
#include<stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include <errno.h>
#include <semaphore.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/stat.h>
#define BUFFER_SIZE 2 //缓存区单元数
sem_t mutex,full,empty; //三个信号量
//缓冲区
struct DataBuffer
{
int buffer[BUFFER_SIZE];
int count;//当前产品数量
}dataBuffer;
//移动缓冲区
void moveDataForward(){
int i;
for(i=0;i<dataBuffer.count;i++)
dataBuffer.buffer[i]=dataBuffer.buffer[i+1];
}
//产品送入缓冲区
void push(int data){
dataBuffer.buffer[dataBuffer.count++]=data;
}
//从缓冲区取产品
int pop(){
int data=dataBuffer.buffer[0];
dataBuffer.count--;
moveDataForward();
return data;
}
//生产者线程
void *producer(void *arg){
int product;
int a;
a=*((int*)arg);
srand(time(NULL));
product=rand()%1000+a;
sleep(1);
printf("生产者 %d 生产一个产品%d\n",a,product);
sleep(1);
printf("生产者 %d 申请缓冲区\n",a);
sleep(1);
sem_wait(&empty);
sem_wait(&mutex);
printf("生产者 %d 申请缓冲区成功\n",a);
sleep(1);
printf("生产者 %d 将产品%d放入缓冲区\n",a,product);
sleep(1);
push(product);
sem_post(&mutex);
sem_post(&full);
printf("生产者 %d 释放缓冲区,当前缓冲区共%d个产品\n",a,dataBuffer.count);
}
//消费者线程
void *customer(void *arg){
int d;
int a;
a=*((int*)arg);
sleep(1);
printf("消费者 %d 申请缓冲区\n",a);
sleep(1);
sem_wait(&full);
sem_wait(&mutex);
printf("消费者 %d 申请缓冲区成功\n",a);
sleep(1);
d=pop();
printf("消费者 %d 从缓冲区取出产品%d\n",a,d);
sleep(1);
sem_post(&mutex);
sem_post(&empty);
printf("消费者 %d 释放缓冲区,当前缓冲区共%d个产品\n",a,dataBuffer.count);
}
int main(){
pthread_t thrd_prd1,thrd_prd2,thrd_prd3,thrd_cst1,thrd_cst2,thrd_cst3;
int i1=1,i2=2,i3=3;
sem_init(&mutex, 0, 1);
sem_init(&empty, 0, BUFFER_SIZE);
sem_init(&full, 0, 0);
pthread_create(&thrd_prd1, NULL, producer, (void *)&i1);
pthread_create(&thrd_prd2, NULL, producer, (void *)&i2);
pthread_create(&thrd_prd3, NULL, producer, (void *)&i3);
pthread_create(&thrd_cst1, NULL, customer, (void *)&i1);
pthread_create(&thrd_cst2, NULL, customer, (void *)&i2);
pthread_create(&thrd_cst3, NULL, customer, (void *)&i3);
pthread_join(thrd_prd1, NULL);
pthread_join(thrd_prd2, NULL);
pthread_join(thrd_prd3, NULL);
pthread_join(thrd_cst1, NULL);
pthread_join(thrd_cst2, NULL);
pthread_join(thrd_cst3, NULL);
return 0;
}
命令行:
gcc xx.c -o xx -lpthread
欢迎关注
掘金:https://juejin.cn/user/4156573190724030
Github:https://github.com/zhubingran
CSDN:https://blog.csdn.net/qq_43118757
QQ:1330022055
版权声明:本文为qq_43118757原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。