進程調度算法-生產者消費者問題

@進程調度算法之生產者消費者問題

生產者消費者問題

問題介紹

生產者生產產品,消費者消費產品,兩者的資源存儲在同一個資源池
因此,問題來了,生產者生產商品需要在資源池的存儲範圍內;然而消費者消費的資源需要在資源池不爲空的前提下。由於兩者均會對資源池造成修改,爲了保證統一性,因此,兩者需要互斥訪問,同時,生產者生產產品需要對生產數量資源進行更改,因此生產者也需要互斥訪問。

ProCon.c 代碼實現

#include <stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include <pthread.h>
#define N 100
#define true 1
#define producerNum  10
#define consumerNum  5
#define sleepTime 1000
//互斥信號量
typedef int semaphore;
typedef int item;
item buffer[N] = {0};
int in = 0;
int out = 0;
int proCount = 0;
//互斥訪問資源池信號量mutex,互斥改變生產商品數量信號量proCmutex
semaphore mutex = 1, empty = N, full = 0, proCmutex = 1;

void * producer(void * a){
    while(true){
//等待佔用proCount資源
        while(proCmutex <= 0);
//佔有資源並改變資源後釋放
        proCmutex--;
        proCount++;
        printf("生產一個產品ID%d, 緩衝區位置爲%d\n",proCount,in);
        proCmutex++;

        while(empty <= 0){
            printf("緩衝區已滿!\n");
        }
        empty--;

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

        buffer[in] = proCount;
        in = (in + 1) % N;

        mutex++;
        full++;
        sleep(sleepTime);
    }
}

void * consumer(void *b){
    while(true){
        while(full <= 0){
            printf("緩衝區爲空!\n");
        }
        full--;

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

//nextc存儲消費的商品
        int nextc = buffer[out];
//消費完將緩衝區設置爲0
        buffer[out] = 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表示線程ID ,unsigned long int
        pthread_t temp;
        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;
}

編譯

gcc -pthread ProCon.c -o ProCon

運行

./ProCon

知識補充:

//創建線程池
pthread_t threadPool[poolNum];
//創建線程,(指向線程標識符的指針,設置線程屬性,線程運行函數的起始地址,運行函數的參數)
pthread_create(&temp, NULL, producer, NULL);
//定義無類型指針。void *也可以無需強制類型轉換地賦給其它類型的指針。因爲“無類型”可以包容“有類型”,而“有類型”則不能包容“無類型”
void * result;

參考自生產者消費者問題C語言實現

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章