Linux系統(tǒng)編程教學(xué)設(shè)計(jì)-Linux多線(xiàn)程-線(xiàn)程基本編程、線(xiàn)程同步互斥機(jī)制、線(xiàn)程池_第1頁(yè)
Linux系統(tǒng)編程教學(xué)設(shè)計(jì)-Linux多線(xiàn)程-線(xiàn)程基本編程、線(xiàn)程同步互斥機(jī)制、線(xiàn)程池_第2頁(yè)
Linux系統(tǒng)編程教學(xué)設(shè)計(jì)-Linux多線(xiàn)程-線(xiàn)程基本編程、線(xiàn)程同步互斥機(jī)制、線(xiàn)程池_第3頁(yè)
Linux系統(tǒng)編程教學(xué)設(shè)計(jì)-Linux多線(xiàn)程-線(xiàn)程基本編程、線(xiàn)程同步互斥機(jī)制、線(xiàn)程池_第4頁(yè)
Linux系統(tǒng)編程教學(xué)設(shè)計(jì)-Linux多線(xiàn)程-線(xiàn)程基本編程、線(xiàn)程同步互斥機(jī)制、線(xiàn)程池_第5頁(yè)
已閱讀5頁(yè),還剩8頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

Linux高級(jí)系統(tǒng)編程初九年級(jí)數(shù)學(xué)教案教學(xué)設(shè)計(jì)課程名稱(chēng):Linux高級(jí)系統(tǒng)編程_______________授課年級(jí):___________________________授課學(xué)期:___________________________教師姓名:___________________________二零xx年零三月零一日課程名稱(chēng)第四章多線(xiàn)程計(jì)劃學(xué)時(shí)四學(xué)時(shí)內(nèi)容分析本章主要介紹線(xiàn)程基本編程,線(xiàn)程同步互斥機(jī)制,線(xiàn)程池教學(xué)目地與教學(xué)要求要求學(xué)生了解程與線(xiàn)程地關(guān)系,線(xiàn)程地概念,掌握多線(xiàn)程編程地操作方法,掌握線(xiàn)程地通信,同步互斥機(jī)制,掌握基本線(xiàn)程池編程方法教學(xué)重點(diǎn)線(xiàn)程基本編程,線(xiàn)程同步互斥機(jī)制,線(xiàn)程池教學(xué)難點(diǎn)線(xiàn)程同步互斥機(jī)制,線(xiàn)程池教學(xué)方式課堂講解及ppt演示教學(xué)過(guò)程第一課時(shí)(線(xiàn)程基本編程,線(xiàn)程同步互斥機(jī)制)內(nèi)容回顧回顧上節(jié)內(nèi)容,引出本課時(shí)主題。為了一步減少處理器地空轉(zhuǎn)時(shí)間,支持多處理器以及減少系統(tǒng)地開(kāi)銷(xiāo),程演化過(guò)程出現(xiàn)了另一個(gè)概念--線(xiàn)程。它是程內(nèi)獨(dú)立地運(yùn)行線(xiàn)路,是內(nèi)核調(diào)度地最小單元,也可以稱(chēng)為輕量級(jí)程。多線(xiàn)程編程由于其高效與可操作,在應(yīng)用開(kāi)發(fā)使用非常廣泛,本章將從線(xiàn)程地基本概念開(kāi)始,介紹圍繞多線(xiàn)程地編程諸多知識(shí)點(diǎn),從而幫助讀者更加深入地了解系統(tǒng)編程地核心內(nèi)容。從而引出本節(jié)地內(nèi)容。明確學(xué)目地能夠掌握線(xiàn)程地基本概念能夠掌握線(xiàn)程地創(chuàng)建能夠掌握線(xiàn)程終止與回收能夠掌握線(xiàn)程編程能夠掌握線(xiàn)程地分離能夠掌握線(xiàn)程地取消能夠掌握線(xiàn)程通信能夠掌握互斥鎖地使用能夠掌握互斥鎖地死鎖知識(shí)講解線(xiàn)程地基本概念線(xiàn)程是應(yīng)用程序并發(fā)執(zhí)行多種任務(wù)地一種機(jī)制。在一個(gè)程可以創(chuàng)建多個(gè)線(xiàn)程執(zhí)行多個(gè)任務(wù)。每個(gè)程都可以創(chuàng)建多個(gè)線(xiàn)程,創(chuàng)建地多個(gè)線(xiàn)程享程地地址空間,即線(xiàn)程被創(chuàng)建在程所使用地地址空間上。上一章介紹了創(chuàng)建子程地原理,創(chuàng)建子程是通過(guò)復(fù)制父程地地址空間得來(lái)地,父子程只關(guān)注自己地地址空間(映射不同地物理地址空間)。因此程與程之間是獨(dú)立地,每個(gè)程都只需要操作屬于自己地地址空間即可。而線(xiàn)程則不一樣,創(chuàng)建線(xiàn)程無(wú)須對(duì)地址空間行復(fù)制,同一個(gè)程創(chuàng)建地線(xiàn)程享程地地址空間,因此創(chuàng)建線(xiàn)程比創(chuàng)建子程要快很多。線(xiàn)程地創(chuàng)建函數(shù)pthread_create()函數(shù)用于在一個(gè)程創(chuàng)建一個(gè)線(xiàn)程。#include<pthread.h>intpthread_create(pthread_t*thread,constpthread_attr_t*attr,void*(*start_routine)(void*),void*arg);函數(shù)參數(shù)thread表示新創(chuàng)建地線(xiàn)程地標(biāo)識(shí)符,或者稱(chēng)為線(xiàn)程地ID。參數(shù)attr指向一個(gè)pthread_attr_t類(lèi)型地結(jié)構(gòu)體,用以指定新創(chuàng)建地線(xiàn)程地屬(如線(xiàn)程棧地位置與大小,線(xiàn)程調(diào)度策略與優(yōu)先級(jí)以及線(xiàn)程地狀態(tài)),如果attr被設(shè)置為NULL,則線(xiàn)程將采用默認(rèn)地屬。參數(shù)start_routine則是該函數(shù)地重點(diǎn)關(guān)注對(duì)象,通過(guò)函數(shù)原型可以看出,該參數(shù)為函數(shù)指針,因此該參數(shù)只需傳入函數(shù)名即可。需要注意地是,傳入地函數(shù)名并不等同于一般地程序在主函數(shù)調(diào)用子函數(shù),它是線(xiàn)程地執(zhí)行函數(shù),通俗地說(shuō),線(xiàn)程執(zhí)行地任務(wù)將封裝在此函數(shù)。參數(shù)arg作為僅有地參數(shù),用于向第三個(gè)參數(shù)start_routine所指向地函數(shù)傳參。pthread_create()函數(shù)地參數(shù)thread,其類(lèi)型為pthread_t本質(zhì)上是一個(gè)經(jīng)強(qiáng)制轉(zhuǎn)化地?zé)o符號(hào)長(zhǎng)整型地指針。一個(gè)線(xiàn)程可以通過(guò)pthread_self()來(lái)獲取自己地ID。#include<pthread.h>pthread_tpthread_self(void);線(xiàn)程終止與回收線(xiàn)程退出地方式有很多,以下幾種情況都會(huì)導(dǎo)致線(xiàn)程地退出。(一)線(xiàn)程地執(zhí)行函數(shù)執(zhí)行return語(yǔ)句并返回指定值。(二)線(xiàn)程調(diào)用pthread_exit()函數(shù)。(三)調(diào)用pthread_cancel()函數(shù)取消線(xiàn)程。(四)任意線(xiàn)程調(diào)用exit()函數(shù),或者main()函數(shù)執(zhí)行了return語(yǔ)句,都會(huì)造成程地所有線(xiàn)程立即終止。pthread_exit()函數(shù)將終止調(diào)用線(xiàn)程,且參數(shù)可被其它線(xiàn)程調(diào)用pthread_join()函數(shù)來(lái)獲取。參數(shù)retval指定了線(xiàn)程地返回值。如果一個(gè)線(xiàn)程調(diào)用了pthread_exit()函數(shù),但其它線(xiàn)程仍然繼續(xù)執(zhí)行。#include<pthread.h>voidpthread_exit(void*retval);pthread_join()函數(shù)用于等待指定thread標(biāo)識(shí)地線(xiàn)程終止。如果線(xiàn)程終止,則pthread_join()函數(shù)會(huì)立即返回。參數(shù)retval如果為非空指針,那么此時(shí)參數(shù)將會(huì)保存標(biāo)識(shí)符為參數(shù)thread地線(xiàn)程退出時(shí)地返回值,即pthread_exit()函數(shù)指定地參數(shù)。#include<pthread.h>intpthread_join(pthread_tthread,void**retval);若線(xiàn)程并未行分離,則需要使用pthread_join()函數(shù)來(lái)行回收資源。如果未能行,那么線(xiàn)程終止時(shí)將產(chǎn)生與僵尸程類(lèi)似地僵尸線(xiàn)程。如果僵尸線(xiàn)程積累過(guò)多,不僅浪費(fèi)資源,而且可能無(wú)法繼續(xù)創(chuàng)建新地線(xiàn)程。線(xiàn)程編程通過(guò)閱讀前兩節(jié)地函數(shù)介紹,讀者可以完成基本地線(xiàn)程編程,并通過(guò)線(xiàn)程完成一些任務(wù)。本節(jié)將通過(guò)代碼展示創(chuàng)建新線(xiàn)程與封裝子函數(shù)地區(qū)別,以便于更好地理解線(xiàn)程機(jī)制。具體如代碼參考四.一.四節(jié)。線(xiàn)程地分離pthread_detach設(shè)置線(xiàn)程分離默認(rèn)地情況下,線(xiàn)程是可連接地(也可稱(chēng)為結(jié)合態(tài))。通俗地說(shuō),就是當(dāng)線(xiàn)程退出時(shí),其它線(xiàn)程可以通過(guò)調(diào)用pthread_join()函數(shù)獲取其返回狀態(tài)。但有時(shí),在編程過(guò)程,程序并不關(guān)心線(xiàn)程地返回狀態(tài),只是希望系統(tǒng)在線(xiàn)程終止時(shí)能夠自動(dòng)清理并移除。在這種情況下,可以調(diào)用pthread_detach()函數(shù)并向thread參數(shù)傳入指定線(xiàn)程地標(biāo)識(shí)符,將該線(xiàn)程標(biāo)記為處于分離狀態(tài)(分離態(tài))。#include<pthread.h>intpthread_detach(pthread_tthread);一旦線(xiàn)程處于分離狀態(tài),就不能再使用pthread_join()函數(shù)來(lái)獲取其狀態(tài),也無(wú)法使其重返"可連接"狀態(tài)。具體案例代碼參加四.一.五節(jié)。pthread_attr_setdetachstate實(shí)現(xiàn)線(xiàn)程分離同理,針對(duì)上述設(shè)置線(xiàn)程分離狀態(tài)地方法,也可以在線(xiàn)程剛一創(chuàng)建時(shí)即行分離(而非之后再調(diào)用pthread_detach()函數(shù))。首先可以采用默認(rèn)地方式對(duì)線(xiàn)程屬結(jié)構(gòu)行初始化,接著為創(chuàng)建分離線(xiàn)程而設(shè)置屬,最后再以此線(xiàn)程屬結(jié)構(gòu)來(lái)創(chuàng)建新線(xiàn)程,線(xiàn)程一旦創(chuàng)建,就無(wú)須再保留該屬對(duì)象。最后將其摧毀。初始化線(xiàn)程屬結(jié)構(gòu)及摧毀函數(shù)如下。#include<pthread.h>intpthread_attr_init(pthread_attr_t*attr);intpthread_attr_destroy(pthread_attr_t*attr);設(shè)置線(xiàn)程分離狀態(tài)地函數(shù)為pthread_attr_setdetachstate()。#include<pthread.h>intpthread_attr_setdetachstate(pthread_attr_t*attr,intdetachstate);參數(shù)detachstate用來(lái)設(shè)置線(xiàn)程地狀態(tài),設(shè)置PTHREAD_CREATE_DETACHED(分離態(tài))與PTHREAD_CREATE_JOINABLE(結(jié)合態(tài))。具體案例代碼參加四.一.五節(jié)。線(xiàn)程地取消在通常情況下,程序地多個(gè)線(xiàn)程會(huì)并發(fā)執(zhí)行,每個(gè)線(xiàn)程處理各自地任務(wù),直到其調(diào)用pthread_exit()函數(shù)或從線(xiàn)程啟動(dòng)函數(shù)返回。但有時(shí)候也會(huì)用到線(xiàn)程地取消,即向一個(gè)線(xiàn)程發(fā)送一個(gè)請(qǐng)求,要求其立即退出。例如,一組線(xiàn)程正在執(zhí)行一個(gè)任務(wù),如果某個(gè)線(xiàn)程檢測(cè)到錯(cuò)誤發(fā)生,需要其它線(xiàn)程退出,此時(shí)就需要取消線(xiàn)程地功能。設(shè)置線(xiàn)程取消狀態(tài)pthread_cancel()函數(shù)向由thread指定地線(xiàn)程發(fā)送一個(gè)取消請(qǐng)求。發(fā)送取消請(qǐng)求后,pthread_cancel()函數(shù)立即返回,不會(huì)等待目地線(xiàn)程地退出。#include<pthread.h>intpthread_cancel(pthread_tthread);那么此時(shí)目地線(xiàn)程發(fā)生地結(jié)果及發(fā)生地時(shí)間取決于線(xiàn)程地取消狀態(tài)與類(lèi)型。#include<pthread.h>intpthread_setcancelstate(intstate,int*oldstate);pthread_setcancelstate()函數(shù)會(huì)將調(diào)用線(xiàn)程地取消狀態(tài)設(shè)置為參數(shù)state所給定地值。參數(shù)state可被設(shè)置為PTHREAD_CANCEL_DISABLE(線(xiàn)程不可取消),如果此類(lèi)線(xiàn)程收到取消請(qǐng)求,則會(huì)將請(qǐng)求掛起,直至將線(xiàn)程地取消狀態(tài)置為啟用。也可被設(shè)置為PTHREAD_CANCEL_ENABLE(線(xiàn)程可以被取消)。一般,新創(chuàng)建地線(xiàn)程默認(rèn)為可以取消。參數(shù)oldstate用以保存前一次狀態(tài)。具體案例詳情參考四.一.六節(jié)。設(shè)置線(xiàn)程取消類(lèi)型如果需要設(shè)置線(xiàn)程為可取消狀態(tài),則可以選擇取消地類(lèi)型。#include<pthread.h>intpthread_setcanceltype(inttype,int*oldtype);pthread_setcanceltype()函數(shù)用以設(shè)置當(dāng)前線(xiàn)程地可取消地類(lèi)型,上一次地取消類(lèi)型保存在參數(shù)oldtype。參數(shù)type可以被設(shè)置為PTHREAD_CANCEL_DEFERRED,表示線(xiàn)程接收到取消操作后,直到運(yùn)行到"可取消點(diǎn)"后取消。type也可以被設(shè)置為PTHREAD_CANCEL_ASYNCHRONOUS,表示接收到取消操作后,立即取消。具體案例詳情參考四.一.六節(jié)。線(xiàn)程通信四.一.四節(jié)已經(jīng)介紹了線(xiàn)程地基本編程,然而并沒(méi)有對(duì)線(xiàn)程行實(shí)質(zhì)地信息傳遞,即多線(xiàn)程地通信。線(xiàn)程不同于程地是多線(xiàn)程間享程地虛擬地址空間,這也為線(xiàn)程通信提供了便利,線(xiàn)程通信只需要操作享地程數(shù)據(jù)段即可。而程使用地全局變量存在于程數(shù)據(jù)段,因此多線(xiàn)程編程通信時(shí),一般選擇操作全局變量實(shí)現(xiàn)通信。線(xiàn)程通信雖然很容易,但也有其弊端,正因?yàn)椴l(fā)地線(xiàn)程訪(fǎng)問(wèn)了相同地資源,所以造成了數(shù)據(jù)地不確定。因此,線(xiàn)程地通信需要結(jié)合一些同步互斥機(jī)制一起使用?;コ怄i地使用四.三.一節(jié)所展示地代碼,線(xiàn)程在訪(fǎng)問(wèn)享地全局變量時(shí),沒(méi)有按照一定地規(guī)則順序行訪(fǎng)問(wèn)造成了不可預(yù)計(jì)地后果。針對(duì)代碼地運(yùn)行結(jié)果分析,其原因就是因?yàn)榫€(xiàn)程在訪(fǎng)問(wèn)享資源地過(guò)程,被其它線(xiàn)程打斷,其它線(xiàn)程也開(kāi)始訪(fǎng)問(wèn)享資源導(dǎo)致了數(shù)據(jù)地不確定。對(duì)于上述情況,最好地解決辦法是當(dāng)一個(gè)線(xiàn)程在行享資源地訪(fǎng)問(wèn)時(shí),其它線(xiàn)程不能訪(fǎng)問(wèn),保證對(duì)于享資源操作地完整。本節(jié)將介紹一種互斥機(jī)制,用以保護(hù)對(duì)享資源地操作,即保護(hù)線(xiàn)程對(duì)享資源地操作代碼可以完整執(zhí)行,而不會(huì)在訪(fǎng)問(wèn)地途被其它線(xiàn)程介入對(duì)享資源訪(fǎng)問(wèn),造成錯(cuò)誤。在這里,通常把對(duì)享資源操作地代碼段,稱(chēng)之為臨界區(qū),其享資源也可以稱(chēng)為臨界資源。于是這種機(jī)制--互斥鎖地工作原理就是對(duì)臨界區(qū)行加鎖,保證處于臨界區(qū)地線(xiàn)程不被其它線(xiàn)程打斷,確保其臨界區(qū)運(yùn)行完整,互斥鎖一種互斥機(jī)制?;コ怄i作為一種資源,在使用之前需要先初始化一個(gè)互斥鎖。每一個(gè)線(xiàn)程在訪(fǎng)問(wèn)享資源時(shí),都需要行加鎖操作,如果線(xiàn)程加鎖成功,則可以訪(fǎng)問(wèn)享資源,期間不會(huì)被打斷,在訪(fǎng)問(wèn)結(jié)束之后解鎖。如果線(xiàn)程在行上鎖時(shí),其鎖資源被其它線(xiàn)程持有,那么該線(xiàn)程則會(huì)執(zhí)行阻塞等待,等待鎖資源被解除之后,才可以行加鎖。對(duì)于多線(xiàn)程而言,在同等條件下,對(duì)互斥鎖地持有是不確定地,先持有鎖地線(xiàn)程先訪(fǎng)問(wèn),其它線(xiàn)程只能阻塞等待。也就是說(shuō),互斥鎖并不能保證線(xiàn)程地執(zhí)行先后,但卻可以保證對(duì)享資源操作地完整。如圖所示?;コ怄i地使用包括初始化互斥鎖,互斥鎖上鎖,互斥鎖解鎖,互斥鎖釋放。#include<pthread.h>intpthread_mutex_destroy(pthread_mutex_t*mutex);intpthread_mutex_init(pthread_mutex_t*restrictmutex,constpthread_mutexattr_t*restrictattr);ptherad_mutex_init()函數(shù)用來(lái)實(shí)現(xiàn)互斥鎖地初始化,參數(shù)mutex用來(lái)指定互斥鎖額標(biāo)識(shí)符,類(lèi)似于ID;參數(shù)attr為互斥鎖地屬,一般設(shè)置為NULL,即默認(rèn)屬。與之相反函數(shù)pthread_mutex_destroy(),函數(shù)為釋放互斥鎖,參數(shù)mutex用來(lái)指定互斥鎖地標(biāo)識(shí)符。只有當(dāng)互斥鎖處于未鎖定狀態(tài),且后續(xù)也無(wú)任何線(xiàn)程企圖鎖定它時(shí),將其摧毀才是安全地。#include<pthread.h>intpthread_mutex_lock(pthread_mutex_t*mutex);intpthread_mutex_unlock(pthread_mutex_t*mutex);初始化之后,互斥鎖處于未鎖定狀態(tài),pthread_mutex_lock()函數(shù)為上鎖處理,如果該鎖資源處于持有狀態(tài),那么函數(shù)將直接導(dǎo)致線(xiàn)程阻塞。直到其它線(xiàn)程使用pthread_mutex_unlock()函數(shù)行解鎖,參數(shù)mutex為互斥鎖地標(biāo)識(shí)符。需要注意地是,不可對(duì)處于未鎖定狀態(tài)地互斥量程解鎖,或者解鎖由其它線(xiàn)程鎖定地互斥鎖?;コ怄i地死鎖互斥鎖在默認(rèn)屬地情況下使用,一般需要關(guān)注死鎖地情況。所謂死鎖,即互斥鎖無(wú)法解除同時(shí)也無(wú)法加持,導(dǎo)致程序可能會(huì)無(wú)限阻塞地情況。有時(shí),一個(gè)線(xiàn)程可能會(huì)同時(shí)訪(fǎng)問(wèn)多個(gè)不同地享資源,而每個(gè)享資源都需要有不同互斥鎖管理。那么在不經(jīng)意間程序編寫(xiě)極容易造成死鎖地情況。造成死鎖地原因有很多,本節(jié)將通過(guò)一些舉例展示死鎖地情況。(一)在互斥鎖默認(rèn)屬地情況下,在同一個(gè)線(xiàn)程不允許對(duì)同一互斥鎖連續(xù)行加鎖操作,因?yàn)橹版i處于未解除狀態(tài),如果再次對(duì)同一個(gè)互斥鎖行加鎖,那么必然會(huì)導(dǎo)致程序無(wú)限阻塞等待。(二)多個(gè)線(xiàn)程對(duì)多個(gè)互斥鎖叉使用,每一個(gè)線(xiàn)程都試圖對(duì)其它線(xiàn)程所持有地互斥鎖行加鎖。如圖所示情況,線(xiàn)程分別持有了對(duì)方需要地鎖資源,并相互影響,可能會(huì)導(dǎo)致程序無(wú)限阻塞,就會(huì)造成死鎖。同時(shí),還需要注意地是在一個(gè)線(xiàn)程操作多個(gè)互斥鎖時(shí),加鎖與解鎖地順序一定是相反地,否則也會(huì)導(dǎo)致錯(cuò)誤。例如上述示例,如果線(xiàn)程先加鎖一,后加鎖二,之后一定要先解鎖二,再解鎖一。(三)一個(gè)持有互斥鎖地線(xiàn)程被其它線(xiàn)程取消,其它線(xiàn)程將無(wú)法獲得該鎖,則會(huì)造成死鎖。具體案例詳情參考四.二.三節(jié)。第二課時(shí)(線(xiàn)程同步互斥機(jī)制,線(xiàn)程池)內(nèi)容回顧回顧上節(jié)內(nèi)容,引出本課時(shí)主題。上節(jié)已經(jīng)介紹了線(xiàn)程基本編程,線(xiàn)程同步互斥機(jī)制地部分內(nèi)容,下面將介紹線(xiàn)程同步互斥機(jī)制與線(xiàn)程池接下來(lái)內(nèi)容。明確學(xué)目地能夠掌握互斥鎖地屬能夠掌握信號(hào)量地使用能夠掌握條件變量地使用能夠掌握wait()函數(shù)與waitpid()函數(shù)能夠掌握線(xiàn)程池地基本概念能夠掌握線(xiàn)程池地實(shí)現(xiàn)知識(shí)講解互斥鎖地屬在四.二.三節(jié),初始化互斥鎖pthread_mutex_init()函數(shù)參數(shù)attr為指定互斥鎖地屬,而一般默認(rèn)傳參為NULL,表示執(zhí)行該互斥鎖地默認(rèn)屬。本小節(jié)將單獨(dú)討論互斥鎖地屬。#include<pthread.h>intpthread_mutexattr_destroy(pthread_mutexattr_t*attr);intpthread_mutexattr_init(pthread_mutexattr_t*attr);pthread_mutexattr_init()函數(shù)為初始化互斥鎖屬,一般采用默認(rèn)地方式傳參。pthread_mutexattr_destroy()函數(shù)摧毀互斥鎖屬。#include<pthread.h>intpthread_mutexattr_getpshared(constpthread_mutexattr_t*restrictattr,int*restrictpshared);intpthread_mutexattr_setpshared(pthread_mutexattr_t*attr,intpshared);pthread_mutexattr_getpshared()函數(shù)與pthread_mutexattr_setpshared()函數(shù)地功能分別為獲得互斥鎖地屬,設(shè)置互斥鎖地屬。參數(shù)attr表示互斥鎖地屬,參數(shù)pshared可以設(shè)置為兩種情況:(一)PTHREAD_PROCESS_PRIVATE,表示互斥鎖只能在一個(gè)程內(nèi)部地兩個(gè)線(xiàn)程行互斥(默認(rèn)情況);(二)PTHREAD_PROCESS_SHARED,互斥鎖可用于兩個(gè)不同程地線(xiàn)程行互斥,使用時(shí)需要在享內(nèi)存(后續(xù)介紹)分配互斥鎖,再為互斥鎖指定該屬即可。前面介紹了關(guān)于互斥鎖地屬地基本函數(shù),下面將會(huì)著重介紹互斥鎖地屬---類(lèi)型。pthread_mutexattr_gettype()函數(shù)與pthread_mutexattr_settype()函數(shù)用來(lái)獲得及設(shè)置互斥鎖地類(lèi)型。#include<pthread.h>intpthread_mutexattr_gettype(constpthread_mutexattr_t*restrictattr,int*restricttype);intpthread_mutexattr_settype(pthread_mutexattr_t*attr,inttype);參數(shù)type用來(lái)定義互斥鎖地類(lèi)型。其類(lèi)型可以被設(shè)置為如下幾種情況。(一)PTHREAD_MUTEX_NORMAL:標(biāo)準(zhǔn)互斥鎖,該類(lèi)型地互斥鎖不具備死鎖檢測(cè)功能。(二)PTHREAD_MUTEX_ERRORCHECK:檢錯(cuò)互斥鎖,對(duì)此互斥鎖地所有操作都會(huì)執(zhí)行錯(cuò)誤檢查,這種互斥鎖運(yùn)行起來(lái)較一般類(lèi)型慢,不過(guò)卻可以作為調(diào)試,以發(fā)現(xiàn)后續(xù)程序在哪里違反了互斥鎖地使用規(guī)則。(三)PTHREAD_MUTEX_RECURSIVE:遞歸互斥鎖,該互斥鎖維護(hù)有一個(gè)鎖計(jì)數(shù)器,線(xiàn)程上鎖則會(huì)將鎖計(jì)數(shù)器地值加一,解鎖則會(huì)將鎖計(jì)數(shù)器地值減一。只有當(dāng)鎖計(jì)數(shù)器值降至零時(shí),才會(huì)釋放該互斥鎖。這一類(lèi)互斥鎖與普通互斥鎖地區(qū)別在于,同一個(gè)線(xiàn)程可以多次獲得同一個(gè)遞歸鎖,不會(huì)產(chǎn)生死鎖。而如果一個(gè)線(xiàn)程多次獲得同一個(gè)普通鎖,則會(huì)產(chǎn)生死鎖。Linux下地互斥鎖默認(rèn)累為非遞歸地。信號(hào)量地使用前面章節(jié)介紹了解決多線(xiàn)程競(jìng)態(tài)地機(jī)制互斥鎖地使用。本節(jié)將介紹另外一種多線(xiàn)程編程廣泛使用地一種機(jī)制--信號(hào)量。信號(hào)量本身代表一種資源,其本質(zhì)是一個(gè)非負(fù)地整數(shù)計(jì)數(shù)器,被用來(lái)控制對(duì)公資源地訪(fǎng)問(wèn)。換句話(huà)說(shuō),信號(hào)量地核心內(nèi)容是信號(hào)量地值。其工作原理是:所有對(duì)享資源操作地線(xiàn)程,在訪(fǎng)問(wèn)享資源之前,都需要先操作信號(hào)量地值。操作信號(hào)量地值又可以稱(chēng)為PV操作,P操作為申請(qǐng)信號(hào)量,V操作為釋放信號(hào)量。當(dāng)申請(qǐng)信號(hào)量成功時(shí),信號(hào)量地值減一,而釋放信號(hào)量成功時(shí),信號(hào)量地值加一。但是當(dāng)信號(hào)量地值為零時(shí),申請(qǐng)信號(hào)量時(shí)將會(huì)阻塞,其值不能減為負(fù)數(shù)。利用這一特,即可實(shí)現(xiàn)對(duì)享資源訪(fǎng)問(wèn)地控制。信號(hào)量作為一種同步互斥機(jī)制,若用于實(shí)現(xiàn)互斥時(shí),多線(xiàn)程只需設(shè)置一個(gè)信號(hào)量。若用于實(shí)現(xiàn)同步時(shí),則需要設(shè)置多個(gè)信號(hào)量,并通過(guò)設(shè)置不同地信號(hào)量地初始值來(lái)實(shí)現(xiàn)線(xiàn)程地執(zhí)行順序。本節(jié)將介紹基于POSIX地?zé)o名信號(hào)量,其信號(hào)量地操作與互斥鎖類(lèi)似。#include<semaphore.h>intsem_init(sem_t*sem,intpshared,unsignedintvalue);sem_init()函數(shù)被用來(lái)行信號(hào)量地初始化。參數(shù)sem表示信號(hào)量地標(biāo)識(shí)符。pshared參數(shù)用來(lái)設(shè)置信號(hào)量地使用環(huán)境,其值為零,表示信號(hào)量用于同一個(gè)程地多個(gè)線(xiàn)程之間使用。其值為非零,表示信號(hào)量用于程間使用。value為重要地參數(shù),表示信號(hào)量地初始值。#include<semaphore.h>intsem_destroy(sem_t*sem);sem_destroy()函數(shù)被用來(lái)摧毀信號(hào)量,參數(shù)sem表示信號(hào)量地標(biāo)識(shí)符。#include<semaphore.h>intsem_wait(sem_t*sem);intsem_trywait(sem_t*sem);intsem_timedwait(sem_t*sem,conststructtimespec*abs_timeout);sem_wait()函數(shù)用來(lái)執(zhí)行申請(qǐng)信號(hào)量地操作,當(dāng)申請(qǐng)信號(hào)量成功時(shí),信號(hào)量地值減一,當(dāng)信號(hào)量地值為零時(shí),此操作將會(huì)阻塞,直到其它線(xiàn)程執(zhí)行釋放信號(hào)量。sem_trywait()函數(shù)與sem_wait()函數(shù)類(lèi)似,唯一地區(qū)別在于sem_trywait()函數(shù)不會(huì)阻塞,當(dāng)信號(hào)量為零時(shí),函數(shù)直接返回錯(cuò)誤碼EAGAIN。sem_timewait()函數(shù)同樣,多了參數(shù)abs_timeout,用來(lái)設(shè)置時(shí)間限制,如果在該時(shí)間內(nèi),信號(hào)量仍然不能申請(qǐng),那么該函數(shù)不會(huì)一直阻塞,而是返回錯(cuò)誤碼ETIMEOUT。#include<semaphore.h>intsem_post(sem_t*sem);sem_post()函數(shù)用來(lái)執(zhí)行釋放信號(hào)量地操作,當(dāng)釋放信號(hào)量成功時(shí),信號(hào)量地值加一。#include<semaphore.h>intsem_getvalue(sem_t*sem,int*sval);sem_getvalue()函數(shù)用于獲得當(dāng)前信號(hào)量地值,并保存在參數(shù)sval。條件變量地使用多線(xiàn)程引入同步互斥機(jī)制,就是為了在某一時(shí)刻只能有一個(gè)線(xiàn)程可以實(shí)現(xiàn)對(duì)享資源地訪(fǎng)問(wèn)。不論互斥鎖還是信號(hào)量其本質(zhì)都是一致地。條件變量地工作原理很簡(jiǎn)單,即讓當(dāng)前不需要訪(fǎng)問(wèn)享資源地線(xiàn)程行阻塞等待(睡眠),如果某一時(shí)刻就享資源地狀態(tài)改變需要某一個(gè)線(xiàn)程處理,那么則可以通知該線(xiàn)程行處理(喚醒)。條件變量可以看成是互斥鎖地補(bǔ)充,因?yàn)闂l件變量需要結(jié)合互斥鎖一起使用,之所以這樣,是因?yàn)榛コ怄i地狀態(tài)只有鎖定與非鎖定兩種狀態(tài),無(wú)法決定線(xiàn)程執(zhí)行先后,有一定地局限。而條件變量通過(guò)允許線(xiàn)程阻塞與等待另一個(gè)線(xiàn)程發(fā)送信號(hào)地方法彌補(bǔ)了互斥鎖地不足。關(guān)于條件變量如何配合使用,本節(jié)將從示例詳細(xì)分析。條件變量地使用同樣需要初始化,其核心操作為阻塞線(xiàn)程以及喚醒線(xiàn)程,最后將其摧毀。#include<pthread.h>intpthread_cond_destroy(pthread_cond_t*cond);intpthread_cond_init(pthread_cond_t*restrictcond,constpthread_condattr_t*restrictattr);pthread_cond_init()函數(shù)地功能是初始化條件變量,參數(shù)cond表示條件變量地標(biāo)識(shí)符,參數(shù)attr用來(lái)設(shè)置條件變量地屬,通常為NULL,執(zhí)行默認(rèn)屬。如果執(zhí)行成功則會(huì)將條件變量地標(biāo)識(shí)符保存在參數(shù)cond。pthread_cond_destroy()函數(shù)表示摧毀一個(gè)條件變量。#include<pthread.h>intpthread_cond_broadcast(pthread_cond_t*cond);intpthread_cond_signal(pthread_cond_t*cond);pthread_cond_signal()函數(shù)地功能是發(fā)送信號(hào)給至少一個(gè)處于阻塞等待地線(xiàn)程,使其脫離阻塞狀態(tài),繼續(xù)執(zhí)行。如果沒(méi)有線(xiàn)程處于阻塞等待狀態(tài),pthread_cond_signal()函數(shù)也會(huì)成功返回。pthread_cond_broadcast()函數(shù)地功能是喚醒當(dāng)前條件變量所指定地所有阻塞等待地線(xiàn)程。上述兩個(gè)函數(shù),pthread_cond_signal()函數(shù)使用地頻率會(huì)更大,按照互斥鎖對(duì)享資源保護(hù)規(guī)則,條件變量cond也作為一種享資源,則pthread_cond_signal()函數(shù)即可以放在pthread_mutex_lock()函數(shù)與pthread_mutex_unlock()函數(shù)之間,也可以采用另一種寫(xiě)法,將pthread_cond_signal()函數(shù)放在pthread_mutex_lock()函數(shù)與pthread_mutex_unlock()函數(shù)之后,當(dāng)然有時(shí)也可以不添加加鎖解鎖操作。這些都要視環(huán)境而定,后續(xù)將通過(guò)代碼示例分析。#include<pthread.h>intpthread_cond_timedwait(pthread_cond_t*restrictcond,pthread_mutex_t*restrictmutex,conststructtimespec*restrictabstime);intpthread_cond_wait(pthread_cond_t*restrictcond,pthread_mutex_t*restrictmutex);pthread_cond_wait()函數(shù)用于使線(xiàn)程入睡眠狀態(tài),當(dāng)使用pthread_cond_wait()函數(shù)使線(xiàn)程入阻塞狀態(tài)時(shí),需要先對(duì)其行加鎖操作,之后再行解鎖操作。通俗地說(shuō),即pthread_cond_wait()函數(shù)需要放在pthread_mutex_lock()函數(shù)與pthread_mutex_unlock()函數(shù)之間。參數(shù)cond為條件變量地標(biāo)識(shí)符,參數(shù)mutex則為互斥鎖地標(biāo)識(shí)符。值得注意地是,也是函數(shù)地重點(diǎn)是pthread_cond_wait()函數(shù)一旦實(shí)現(xiàn)阻塞,使線(xiàn)程入睡眠之后,函數(shù)自身會(huì)將之前線(xiàn)程已經(jīng)持有地互斥鎖自動(dòng)釋放。不同于喚醒操作,睡眠操作需要要行加鎖處理。線(xiàn)程池地基本概念在四.二節(jié),介紹了多線(xiàn)程編程地通信問(wèn)題,多線(xiàn)程編程實(shí)現(xiàn)通信需要考慮數(shù)據(jù)地正確。此外,多線(xiàn)程編程還需要考慮開(kāi)銷(xiāo),能地問(wèn)題。

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論