生产者消费者C语言

                                  操作系统生产者消费者问题C语言
#include <stdio.h>
#include <pthread.h>
#include <windows.h>
#define N 100
#define true 1
#define producerNum  15
#define consumerNum  10
#define sleepTime 1000
typedef int semaphore;
typedef int item;
item buffer[N] = {0};
int in = 0;
int out = 0;
int proCount = 0;
semaphore mutex = 1, empty = N, full = 0, proCmutex = 1;
void * producer(void * a){
    while(true){
        while(proCmutex <= 0);
        proCmutex--;
        proCount++;
        printf("生产一个产品ID%d, 缓冲区位置为%d\n",proCount,in);
        proCmutex++;

        while(empty <= 0){
            printf("缓冲区已满!\n");
        }
        empty--;     //P操作申请资源  -1 
        
        /*
		mutex为1时,标识两个进程都未进入需要互斥的临界区,
		       为0时,一个进程进入临界区运行,另一个必须等待,挂入阻塞队列 
		       为-1时,一个进程正在临界区运行,另一个在阻塞队列中 
		*/
        while(mutex <= 0);  
        mutex--;                 //P操作,信号量  -1,避免同时访问缓冲池 

        buffer[in] = proCount;  //将产品放入缓冲池 
        in = (in + 1) % N;

        mutex++;                //V操作释放资源 ,执行完毕,信号量 +1 ,缓冲池可访问 
        full++;                 //V操作 
        Sleep(sleepTime);       //一个进程结束,休眠一定时间,以便观察 
    }
}
void * consumer(void *b){
    while(true){
        while(full <= 0){
            printf("缓冲区为空!\n");
        }
        full--;

        while(mutex <= 0);
        mutex--;

        int nextc = buffer[out];
        buffer[out] = 0;             //消费完将缓冲区设置为0

        out = (out + 1) % N;

        mutex++;
        empty++;

        printf("\t\t\t\t消费一个产品ID%d,缓冲区位置为%d\n", nextc,out);
        Sleep(sleepTime);
    }
}
int main()
{
    pthread_t threadPool[producerNum+consumerNum];//创建线程池 
    int i;
    for(i = 0; i < producerNum; i++){
        pthread_t temp;                          //pthread_t 用来定义线程类型的变量 
        
        //pthread_create 用来创建线程四个参数(指向线程标识符的指针,线程属性(默认属性),函数起始地址,函数参数) 创建失败  -1
        if(pthread_create(&temp, NULL, producer, NULL) == -1) 
		{
            printf("ERROR, fail to create producer%d\n", i);
            exit(1);
        }
        threadPool[i] = temp;
    }//创建生产者进程放入线程池
    for(i = 0; i < consumerNum; i++){
        pthread_t temp;
        if(pthread_create(&temp, NULL, consumer, NULL) == -1){
            printf("ERROR, fail to create consumer%d\n", i);
            exit(1);
        }
        threadPool[i+producerNum] = temp;
    }//创建消费者进程放入线程池
    void * result;
    for(i = 0; i < producerNum+consumerNum; i++){
        if(pthread_join(threadPool[i], &result) == -1){
            printf("fail to recollect\n");
            exit(1);
        }
    }//运行线程池
    return 0;
}

生产者消费者问题主要是在线程调用的基础上多加了P、V操作。其中线程调用主要使用的是pthread。
Windows下使用Dev-C++开发基于pthread的多线程,步骤---->https://blog.csdn.net/qq_41681845/article/details/89715870
需要使用的函数主要是下面的四个函数
1、pthread_t:用来定义一个线程类型的变量
用法 pthread_t x1;
2、pthread_create:建立线程,它有4个参数
pthread_create(&temp, NULL, print_b, NULL);
第一个参数为指向线程标识符的指针,第二个参数用来设置线程属性,第三个参数是线程运行函数的起始地址,最后一个参数是运行函数的参数。这里,我们的函数thread不需要参数,所以最后一个参数设为空指针。第二个参数我们也设为空指针,这样将生成默认属性的线程。
3、pthread_join:用来等待一个线程的结束,也可以理解为线程开始
第一个参数为被等待的线程标识符,第二个参数为一个用户定义的指针,它可以用来存储被等待线程的返回值。
pthread_join(threadPool[i], &result);
4、pthread_exit:一个线程的结束有两种途径,一种函数结束了,调用它的线程也就结束了;另一种方式是通过函数pthread_exit来实现

运行结果:
在这里插入图片描述

  • 9
    点赞
  • 74
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值