生產(chǎn)者—消費(fèi)者的Linux多線程實(shí)現(xiàn)_第1頁
生產(chǎn)者—消費(fèi)者的Linux多線程實(shí)現(xiàn)_第2頁
生產(chǎn)者—消費(fèi)者的Linux多線程實(shí)現(xiàn)_第3頁
生產(chǎn)者—消費(fèi)者的Linux多線程實(shí)現(xiàn)_第4頁
生產(chǎn)者—消費(fèi)者的Linux多線程實(shí)現(xiàn)_第5頁
已閱讀5頁,還剩2頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、生產(chǎn)者消費(fèi)者的 Linux 多線程實(shí)現(xiàn)1 線程基本概念1.1 進(jìn)程和線程 可執(zhí)行文件由指令和數(shù)據(jù)組成。進(jìn)程就是 在計(jì)算機(jī)上運(yùn)行的可執(zhí)行文件針對(duì)特定的輸入數(shù)據(jù)的一個(gè)實(shí)例, 同一個(gè)可執(zhí)行程序文件如果操作不同的輸入數(shù)據(jù)就是兩個(gè)不同 的進(jìn)程。線程是進(jìn)程的一條執(zhí)行路徑,它包含獨(dú)立的堆棧和CPU寄存 器狀態(tài), 每個(gè)線程共享其所附屬的進(jìn)程的所有的資源, 包括打開 的文件、頁表(因此也就共享整個(gè)用戶態(tài)地址空間)、信號(hào)標(biāo)識(shí) 及動(dòng)態(tài)分配的內(nèi)存等等。Linux 中線程調(diào)度是由內(nèi)核調(diào)度程序完成的,每個(gè)線程有自 己的 ID 號(hào)。與進(jìn)程相比,它們消耗的系統(tǒng)資源較少、創(chuàng)建較快、 相互間的通信也比較容易。 存在于同一進(jìn)程中的

2、線程會(huì)共享一些 信息。同時(shí)作為一個(gè)獨(dú)立的線程, 它們又擁有一些區(qū)別于其他線 程的信息,包括線程ID、寄存器集合(如程序計(jì)數(shù)器和堆棧指 針)、堆棧、錯(cuò)誤號(hào)、信號(hào)掩碼以及線程優(yōu)先權(quán)。線程和進(jìn)程的關(guān)系是: 線程是屬于進(jìn)程的, 線程運(yùn)行在進(jìn)程 空間內(nèi), 同一進(jìn)程所產(chǎn)生的線程共享同一物理內(nèi)存空間, 當(dāng)進(jìn)程 退出時(shí)該進(jìn)程所產(chǎn)生的線程都會(huì)被強(qiáng)制退出并清除。1.2 線程優(yōu)點(diǎn) 它是一種非?!肮?jié)儉”的多任務(wù)操作方式。 運(yùn)行于一個(gè)進(jìn) 程中的多個(gè)線程,使用的是同一個(gè)地址空間,共享大部分?jǐn)?shù)據(jù), 不需要太多的空間啟動(dòng)一個(gè)線程, 而且,線程間彼此切換所需的 時(shí)間也比較短。 線程間方便的通信機(jī)制。 由于同一進(jìn)程下的線 程之間

3、共享數(shù)據(jù)空間, 所以一個(gè)線程的數(shù)據(jù)可以直接為其它線程 所用,這不僅快捷,而且方便。使多 CPU系統(tǒng)更加有效。操作 系統(tǒng)會(huì)保證當(dāng)線程數(shù)不大于 CPU數(shù)目時(shí),不同的線程運(yùn)行于不同 的CPU上。改善程序結(jié)構(gòu)。一個(gè)既長又復(fù)雜的進(jìn)程可以考慮 分為多個(gè)線程, 成為幾個(gè)獨(dú)立或半獨(dú)立的運(yùn)行部分, 便于理解和 修改。2 生產(chǎn)者 - 消費(fèi)者問題2.1問題概述 生產(chǎn)/消費(fèi)者在有界緩沖上操作,它利用N個(gè) 字節(jié)的共享內(nèi)存作為有界循環(huán)緩沖區(qū), 生產(chǎn)者線程不斷順序地將 0到 1000的數(shù)字寫入共享的循環(huán)緩沖區(qū),同時(shí)消費(fèi)者線程不斷 地從共享的循環(huán)緩沖區(qū)讀取數(shù)據(jù)。 利用寫一個(gè)數(shù)據(jù)模擬放一個(gè)產(chǎn) 品,利用讀一個(gè)數(shù)據(jù)模擬消費(fèi)一個(gè)產(chǎn)品

4、。 當(dāng)緩沖區(qū)空時(shí)消費(fèi)者應(yīng) 阻塞睡眠, 而當(dāng)緩沖區(qū)滿時(shí)生產(chǎn)者應(yīng)當(dāng)阻塞睡眠。 一旦緩沖區(qū)中 有空單元, 生產(chǎn)者線程就向空單元中寫入數(shù)據(jù)。 一旦緩沖區(qū)中有 未讀過的數(shù)據(jù),消費(fèi)者線程就從該單元中讀出數(shù)據(jù)。2.2 算法分析 生產(chǎn)者線程向循環(huán)緩沖區(qū)中寫入數(shù)據(jù),消費(fèi) 者線程從緩沖區(qū)中讀取數(shù)據(jù), 生產(chǎn)者線程向緩沖區(qū)中寫入數(shù)據(jù)時(shí) 消費(fèi)者線程不能訪問緩沖區(qū), 消費(fèi)者線程從緩沖區(qū)中讀取數(shù)據(jù)時(shí) 生產(chǎn)者線程也不能訪問緩沖區(qū), 既讀的時(shí)候不能寫, 寫的時(shí)候不 能讀,得保證緩沖區(qū)這一臨界資源同一時(shí)間只能被一個(gè)線程訪 問;緩沖區(qū)滿的時(shí)候不能生產(chǎn),空的時(shí)候不能消費(fèi)。2.2.1 主程序:初始化結(jié)構(gòu)體 prodcons 中的各個(gè)參

5、數(shù);建 立生產(chǎn)者、消費(fèi)者線程;等待線程結(jié)束。222生產(chǎn)者線程:設(shè)初始寫入的數(shù)據(jù) N為0;判斷N小 于1000是否成立;如果不成立,循環(huán)緩沖區(qū)插入OVER如果成立,向循環(huán)緩沖區(qū)生產(chǎn)既寫入 N并打印;重復(fù)該過程直到N=1000 為止。生產(chǎn)產(chǎn)品的函數(shù) put :獲得互斥鎖;判斷循環(huán)緩沖池是 否滿,如果滿將生產(chǎn)者線程阻塞到滿的條件變量 b-notfull 上, 并將互斥鎖釋放,讓消費(fèi)者線程讀取數(shù)據(jù)。如果不滿,向緩沖中 寫入數(shù)據(jù);如果有線程阻塞到環(huán)境變量 b-empty ,將該線程喚 醒,同時(shí)釋放互斥鎖。如果沒有線程阻塞到條件變量 b-empty 上,就直接釋放互斥鎖。2.2.3 消費(fèi)者線程: 從循環(huán)緩

6、沖區(qū)中消費(fèi)既讀取數(shù)據(jù)并打 印;判斷讀取的數(shù)據(jù)是否是結(jié)束標(biāo)志 over ,如果是退出。如果 不是,重復(fù)該過程,直到讀到的數(shù)據(jù)是結(jié)束標(biāo)志 over 。消費(fèi) 產(chǎn)品的函數(shù) get :獲得互斥鎖;判斷循環(huán)緩沖池是否空,如果空 將生產(chǎn)者線程阻塞到空的條件變量 b-empty 上,并將互斥鎖釋 放,讓生產(chǎn)者線程寫數(shù)據(jù)。如果不空,從緩沖中讀取數(shù)據(jù);如果 有線程阻塞到環(huán)境變量 b-notfull 上,將該線程喚醒,同時(shí)釋 放互斥鎖。如果沒有線程阻塞到條件變量 b-notfull 上,就直 接釋放互斥鎖。2.3 數(shù)據(jù)結(jié)構(gòu)struct prodcons int bufferBUFFER_SIZE ; /* the

7、actual data */ pthread_mutex_t lock ; /* mutex ensuring exclusive access to buffer */int readpos , writepos ; /* positions for reading and writing */ pthread_cond_t notempty ; /* signaled when buffer is not empty */pthread_cond_t notfull ;/* signaled whenbuffer is not full */;緩沖區(qū)采用循環(huán)緩沖區(qū)。緩沖區(qū)滿的條件( b-w

8、ritepos +1)% BUFFER_SIZE= b-readpos 。緩沖區(qū)空的條件b-writepos= b-readpos 。2.4 相關(guān)函數(shù)調(diào)用2.4.1 線程函數(shù)創(chuàng)建線程函數(shù): 原型: int pthread_create(pthread_t* thread , const pthread_attr_t * attr , void *( * start )( void * ), void * arg );生產(chǎn)者 - 消費(fèi)者問題中創(chuàng)建的線程:創(chuàng)建 producer 線程: pthread_create (&th_a , NULL, producer , 0 );創(chuàng)建 consumer

9、 線程: pthread_create (&th_b , NULL, consumer, 0 );Pthread_create 函數(shù)中第一個(gè)參數(shù)為指向線程標(biāo)識(shí)符的指 針,第二個(gè)參數(shù)用來設(shè)置線程屬性,兩個(gè)線程該參數(shù)均為NULL,為系統(tǒng)配置的默認(rèn)屬性;第三個(gè)參數(shù)是線程運(yùn)行函數(shù)的起始地 址,最后一個(gè)參數(shù)是運(yùn)行函數(shù)的參數(shù)。當(dāng)創(chuàng)建線程成功時(shí),函數(shù) 返回 0 。 等待線程結(jié)束函數(shù) 原型: extern int pthread_join( pthread_t _th , void * * _thread_return);第一個(gè)參數(shù)為被等待的線程標(biāo)識(shí)符, 第二個(gè)參數(shù)為一個(gè)用戶 定義的指針,它可以用來存儲(chǔ)被等待

10、線程的返回值。生產(chǎn)者 -消費(fèi)者問題中等待結(jié)束的線程:pthread_join ( th_a , &retval ); pthread_join (th_b , &retval ); 終止線程 原型: extern void pthread_exit ( void * status );函數(shù)參數(shù) status 是指向線程返回值得指針。2.4.2 互斥鎖函數(shù) 一個(gè)進(jìn)程中的多個(gè)線程是共享同一段資 源的,由于線程對(duì)資源的競爭引出了鎖。 互斥鎖用來保證一段時(shí) 間內(nèi)只有一個(gè)線程在執(zhí)行一段代碼。 其中 mutex 是一種簡單的加 鎖方法,這個(gè)互斥鎖只有兩種狀態(tài),那就是上鎖和解鎖。在某一 時(shí)刻,只能有一個(gè)線程

11、取得這個(gè)互斥上的鎖, 擁有上鎖狀態(tài)的線 程可以對(duì)共享資源進(jìn)行操作,而其他線程在該線程未解鎖之前, 會(huì)被掛起,直到上鎖的線程解開鎖?;コ怄i初始化函數(shù):int pthread_mutex_init( pthread_mutex_t* mutex ,const pthread_mutexattr_t* mutexattr ); 第一個(gè)參數(shù)為指向互斥鎖的指針,第二個(gè)參數(shù)為鎖的屬性, 該問題中設(shè)為NULL為默認(rèn)分配的屬性?;コ怄i上鎖函數(shù):int pthread_mutex_lock( pthread_mutex_t* mutex );pthread_mutex_lock 聲明開始用互斥鎖上鎖,此后的代碼

12、 直至調(diào)用 pthread_mutex_unlock 為止,均被上鎖,即同一時(shí)間 只能被一個(gè)線程調(diào)用執(zhí)行。條件變量:關(guān)于互斥鎖的一個(gè)很顯然的不足之處就是它僅存 在兩種狀態(tài): 即鎖定和非鎖定。 實(shí)際上它的這一缺點(diǎn)是可以根據(jù) 條件變量通過允許線程阻塞和等待另一個(gè)線程發(fā)送信號(hào)的方法 來改善的,條件變量經(jīng)常與互斥鎖同時(shí)使用。 條件變量初始化函數(shù)。原型:int pthread_cond_init ( pthread_cond_t * cond, const pthread_condattr_t * cond_attr );第 1個(gè)函數(shù)參數(shù)表示要初始化的條件變量對(duì)象, 第 2個(gè)參數(shù) 是條件變量的屬性。生產(chǎn)

13、者 -消費(fèi)者問題中用到兩個(gè)條件變量 b-notempty 和 b-notfull 。其中 b-notempty 是緩沖區(qū)滿的時(shí) 候阻塞生產(chǎn)者線程的條件變量, b-notfull 是緩沖區(qū)空的時(shí)候阻塞消費(fèi)者線程的條件變量。兩個(gè)條件變量均應(yīng)初始化。 線程阻塞函數(shù)。原型:extern int pthread_cond_wait (pthread_cond_t * cond , pthread_mutex_t * mutex );第 1 個(gè)參數(shù)就是要等待的條件變量, 第 2 個(gè)參數(shù)則是解鎖 的對(duì)象。生產(chǎn)者 -消費(fèi)者中用到的線程阻塞函數(shù):pthread_cond_wait (&b-notfull , &b-lock );既生產(chǎn) 者線程因?yàn)檠h(huán)緩沖區(qū)滿將自己阻塞到條件變量 b-notfull 上,同時(shí)釋放鎖 &b-lock ,讓消費(fèi)者線程去執(zhí)行。pthread_cond_wait ( &b-notempty , &b-lock );既消費(fèi) 者線程因?yàn)檠h(huán)緩沖區(qū)空將自己阻塞到條件變量 b-notempty 上,同時(shí)釋放鎖 &b-lock ,讓生產(chǎn)者線程去生產(chǎn)。 線程喚醒函數(shù):原型:extern int pthread_cond_signal( pthread_cond_t *cond);

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論