互斥鎖和條件變量實現生產者消費者問題


   同步中有一個稱為生產者-消費者問題的經典問題,也稱為有界緩沖區問題。一個或多個生產者(線程或進程)

創建着一個個的數據條目,然后這些數據條目有一個或多個消費者(線程或進程)處理。數據條目在生產者和消

費者之間是使用某種類型的IPC傳遞的。

   而在我們的單個消費者和單個生產者之間的問題中,使用互斥鎖和條件變量使其同步。而互斥鎖用於上鎖,條

件變量則用於等待。在程序中定義了如下的結構體:

typedef struct pc_st
{
    int buffer[BUFFER_SIZE];
    pthread_mutex_t mutex;
    pthread_cond_t notfull;
    pthread_cond_t notempty;
    int write_pos;
    int read_pos;
}pc_st;

   在結構體中定義了一個數組用於存儲產品,定義了互斥變量,定義了兩個條件變量,定義了兩個位置,當生產

產品時和消費產品時用於判斷數組中是否是滿的還是空的。

   之后定義的結構體變量對其進行初始化,在程序中,主要有兩個函數去實現生產和消費功能,put()函數是實現

生產者生產產品的函數,而get()函數是實現消費者進行消費產品的函數。

   下面是運用互斥鎖和條件變量來實現生產者消費者問題的代碼:

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#define BUFFER_SIZE 8
#define MAX_COUNT 20

typedef struct pc_st
{
    int buffer[BUFFER_SIZE];
    pthread_mutex_t mutex;
    pthread_cond_t notfull;
    pthread_cond_t notempty;
    int write_pos;
    int read_pos;
}pc_st;

#define OVER -1
#define PC_ST_INITIALIZER {{OVER,OVER,OVER,OVER,OVER,OVER,OVER,OVER},PTHREAD_MUTEX_INITIALIZER,PTHREAD_COND_INITIALIZER,PTHREAD_COND_INITIALIZER,0,0}

pc_st pc= PC_ST_INITIALIZER;

void put(int data)
{
    pthread_mutex_lock(&pc.mutex);
    if((pc.write_pos+ 1)%BUFFER_SIZE== pc.read_pos)  
        pthread_cond_wait(&pc.notfull,&pc.mutex);
    pc.buffer[pc.write_pos]= data;
    pc.write_pos= (pc.write_pos+ 1)%BUFFER_SIZE;
    pthread_cond_signal(&pc.notempty);
    pthread_mutex_unlock(&pc.mutex);
}
int get()
{
    int value;
    pthread_mutex_lock(&pc.mutex);
    if(pc.read_pos== pc.write_pos)  
        pthread_cond_wait(&pc.notempty,&pc.mutex);
    value= pc.buffer[pc.read_pos];
    pc.read_pos= (pc.read_pos+ 1)%BUFFER_SIZE;
    pthread_cond_signal(&pc.notfull);
    pthread_mutex_unlock(&pc.mutex);
    return value;
}
void* producer(void *arg)
{
    int i= 1;
    while(i<= MAX_COUNT)
    {
        put(i);
        i++;
    }
    put(OVER);
}
void* consumer(void *arg)
{
    int value;
    while(1)
    {
        value= get();
        if(value== OVER)
            break;
        printf("value= %d\n",value);
        sleep(1);
    }
}
int main()
{
    pthread_t pro_id,con_id;
    pthread_create(&pro_id,NULL,producer,NULL);
    pthread_create(&con_id,NULL,consumer,NULL);
    pthread_join(pro_id,NULL);
    pthread_join(con_id,NULL);
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM