生產者-消費者模型

1. 條件變量+互斥鎖 實現 生產者-消費者模型:數組

/*藉助條件變量模擬 生產者-消費者 問題*/
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>

/*鏈表做爲公享數據,需被互斥量保護*/    //模擬籮筐
struct msg {
    struct msg *next;
    int num;
};

struct msg *head;
struct msg *mp;

/* 靜態初始化 一個條件變量 和 一個互斥量*/
pthread_cond_t has_product = PTHREAD_COND_INITIALIZER;    //條件變量靜態初始化
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;        //互斥鎖靜態初始化

void *consumer(void *p)//消費者
{
    for (;;) {
        pthread_mutex_lock(&lock);//加鎖
        while (head == NULL) {           //頭指針爲空,說明沒有節點    能夠爲if嗎
            pthread_cond_wait(&has_product, &lock);
        }
        mp = head;      
        head = mp->next;    //模擬消費掉一個產品
        pthread_mutex_unlock(&lock);//解鎖

        printf("-Consume ---%d\n", mp->num);
        free(mp);
        mp = NULL;
        sleep(rand() % 5);
    }
}

void *producer(void *p)//生產者
{
    for (;;) {
        mp = malloc(sizeof(struct msg));
        mp->num = rand() % 1000 + 1;        //模擬生產一個產品
        printf("-Produce ---%d\n", mp->num);

        pthread_mutex_lock(&lock);//加鎖
        mp->next = head;//頭插法
        head = mp;
        pthread_mutex_unlock(&lock);//解鎖

        pthread_cond_signal(&has_product);  //將等待在該條件變量上的一個線程喚醒
        sleep(rand() % 5);
    }
}

int main(int argc, char *argv[])
{
    pthread_t pid, cid;
    srand(time(NULL));

    pthread_create(&pid, NULL, producer, NULL);//建立生產者線程
    pthread_create(&cid, NULL, consumer, NULL);//建立消費者線程

    pthread_join(pid, NULL);//回收線程
    pthread_join(cid, NULL);

    return 0;
}

 

2. 信號量 實現 生產者-消費者模型:post

 

/*信號量實現 生產者 消費者問題*/

#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <semaphore.h>

#define NUM 5               

int queue[NUM];                                     //全局數組實現環形隊列
sem_t blank_number, product_number;                 //空格子信號量, 產品信號量

void *producer(void *arg)
{
    int i = 0;

    while (1) {
        sem_wait(&blank_number);                    //生產者將空格子數--,爲0則阻塞等待
        queue[i] = rand() % 1000 + 1;               //生產一個產品,存入隊列
        printf("----Produce---%d\n", queue[i]);        
        sem_post(&product_number);                  //將產品數++

        i = (i+1) % NUM;                            //藉助下標實現環形,下標日後移
        sleep(rand()%3);
    }
}

void *consumer(void *arg)
{
    int i = 0;

    while (1) {
        sem_wait(&product_number);                  //消費者將產品數--,爲0則阻塞等待
        printf("-Consume---%d\n", queue[i]);
        queue[i] = 0;                               //消費一個產品 
        sem_post(&blank_number);                    //消費掉之後,將空格子數++

        i = (i+1) % NUM;
        sleep(rand()%3);
    }
}

int main(int argc, char *argv[])
{
    pthread_t pid, cid;

    sem_init(&blank_number, 0, NUM);                //初始化空格子信號量爲5
    sem_init(&product_number, 0, 0);                //產品數爲0

    pthread_create(&pid, NULL, producer, NULL);    //建立生產者線程
    pthread_create(&cid, NULL, consumer, NULL);    //建立消費者線程

    pthread_join(pid, NULL);    //回收線程
    pthread_join(cid, NULL);

    sem_destroy(&blank_number);    //銷燬信號量
    sem_destroy(&product_number);

    return 0;
}
相關文章
相關標籤/搜索