當前位置:編程學習大全網 - 源碼下載 - 請高手幫忙解釋下這多線程的源代碼,每句註釋下 #include <stdio.h> #include <stdlib.h>

請高手幫忙解釋下這多線程的源代碼,每句註釋下 #include <stdio.h> #include <stdlib.h>

首先這是壹個生產者和消費者問題。

生產者producer負責產生數據,然後通過put操作將數據放到緩沖區buf中。

消費者consumer負責顯示數據,通過get操作從緩沖區buf中讀取數據。

========》

先看主函數main(),

生產者和消費者分別用兩個線程來實現。

主函數中的pthread_create()函數就是用來創建這兩個線程的。

開始定義了兩個變量th_a,th_b用來記錄這兩個線程的線程號。

線程的程序體分別是producer,consumer。

接下來的pthread_join用來等待兩個線程結束。因為如果不等待,main函數的主線程會立即結束,而兩個子線程還來不及完全執行。

=======》

下面來分別看producer,consumer這兩個線程。

producer循環壹百次,每次調用put往buffer中放數據,最後放壹個OVER;

consumer循環用get從buffer中讀到數據並打印,直到讀取的數據位OVER數據時結束。

=======》

我們再分別來看put操作和get操作。

由於put和get都要訪問buf,buf就是壹個臨界資源,為了解決這個臨界資源,在使用buf之前,要對它加鎖。

pthread_mutex_lock(b->lock)壹個為信號量加鎖的函數。每個信號量只能加鎖壹次(我說的可能不準確),如果執行該函數的時候,參數中的信號量已經被加鎖,則該函數阻塞,直到信號量被解鎖才繼續執行。這樣就能保證信號量所保護的臨界資源能夠被互斥的訪問。

struct?prodcons?{?

int?buffer[BUFFER_SIZE];?/*?這個就是循環緩沖區*/?

pthread_mutex_t?lock;?/*這個是信號量,用來保證對緩沖區的互斥訪問*/?

int?readpos,?writepos;/*?這兩個成員分別表示讀位置和寫位置*/?

pthread_cond_t?notempty;?/*?這是表示緩沖區“非空”的條件信號量*/?

pthread_cond_t?notfull;/*?這是表示緩沖區“非滿”的條件信號量*/?

};?

buf是壹個循環的緩沖區,我們先來看緩沖區為空和滿這兩種狀態時,讀、寫標記(readpos,writepos)的位置。

緩沖區為空時,readpos?和writepos指在同壹位置;

換從去為滿時,writepos位置的下壹個位置就是readpos。?

/*?put負責把數據放到緩沖區*/?

void?put(struct?prodcons?*?b,?int?data)?

{?

//首先對互斥信號量進行加鎖

pthread_mutex_lock(&b->lock);?

/*?這裏就是判斷緩沖區有沒有滿,用writepos+1與readpos比較,可以參考附圖。

*?因為是循環緩沖區,所以要模BUFFER_SIZE?。

*?如果緩沖區滿,將在while中等待,直到緩沖區非滿,再繼續執行。

*/?

while?((b->writepos?+?1)?%?BUFFER_SIZE?==?b->readpos)?{?

printf("wait?for?not?full\n");?

//如果已經滿了,則等待消費者讀取了數據後發出“非滿”信號。

pthread_cond_wait(&b->notfull,?&b->lock);?

}?

/*?當緩沖區非滿時,將數據寫入緩沖區中writepos對應的位置*/?

b->buffer[b->writepos]?=?data;?

//更新writepos到下壹個位置

b->writepos++;?

//循環利用緩沖區空間,如果超過了最大值,則從頭開始。

if?(b->writepos?>=?BUFFER_SIZE)?b->writepos?=?0;?

/*?向消費者發送信號,告訴消費者緩沖取非空?*/?

pthread_cond_signal(&b->notempty);?

//對互斥信號進行解鎖。

pthread_mutex_unlock(&b->lock);?

}?

/*--------------------------------------------------------*/?

/*?get負責從緩沖區中讀取數據?*/?

int?get(struct?prodcons?*?b)?

{?

int?data;?

//對互斥信號量進行加鎖

pthread_mutex_lock(&b->lock);?

/*?判斷緩沖區是否為空,為空則等待*/?

while?(b->writepos?==?b->readpos)?{?

printf("wait?for?not?empty\n");?

pthread_cond_wait(&b->notempty,?&b->lock);?

}?

/*?讀取readpos位置的數據?*/?

data?=?b->buffer[b->readpos];?

//更新readpos到下壹個位置。

b->readpos++;?

//循環利用緩沖區,回撥指針

if?(b->readpos?>=?BUFFER_SIZE)?b->readpos?=?0;?

/*?發信號給生產者,緩沖區非滿,可以放數據了*/?

pthread_cond_signal(&b->notfull);?

//對互斥信號量進行解鎖

pthread_mutex_unlock(&b->lock);?

return?data;?

}

  • 上一篇:python異步有哪些方式
  • 下一篇:怎麽解決讀取txt文件讀取時中文亂碼問題
  • copyright 2024編程學習大全網