Linux 生产者消费者问题代码实现

进程间通信(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版权协议,转载请附上原文出处链接和本声明。