Linux互斥鎖、條件變量和信號(hào)量_第1頁(yè)
Linux互斥鎖、條件變量和信號(hào)量_第2頁(yè)
Linux互斥鎖、條件變量和信號(hào)量_第3頁(yè)
Linux互斥鎖、條件變量和信號(hào)量_第4頁(yè)
Linux互斥鎖、條件變量和信號(hào)量_第5頁(yè)
已閱讀5頁(yè),還剩2頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、Linux-Linux互斥鎖、條件變量和信號(hào)量進(jìn)行多線程編程,最應(yīng)該注意的就是那些共享的數(shù)據(jù),因?yàn)闊o法知道哪個(gè)線程會(huì)在哪個(gè)時(shí)候?qū)λM(jìn)行操作,也無法得知哪個(gè)線程會(huì)先運(yùn)行,哪個(gè)線程會(huì)后運(yùn)行。所以,要對(duì)這些資源進(jìn)行合理的分配和正確的使用。在Linux下,提供了互斥鎖、條件變量和信號(hào)量來對(duì)共享資源進(jìn)行保護(hù)。一、互斥鎖互斥鎖,是一種信號(hào)量,常用來防止兩個(gè)進(jìn)程或線程在同一時(shí)刻訪問相同的共享資源。需要的頭文件:pthread.h互斥鎖標(biāo)識(shí)符:pthread_mutex_t(1)互斥鎖初始化:函數(shù)原型: int pthread_mutex_init (pthread_mutex_t* mutex,const

2、pthread_mutexattr_t* mutexattr;函數(shù)傳入值:  mutex:互斥鎖。mutexattr:PTHREAD_MUTEX_INITIALIZER 創(chuàng)建快速互斥鎖。PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP 創(chuàng)建遞歸互斥鎖。PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP  創(chuàng)建檢錯(cuò)互斥鎖。函數(shù)返回值:成功:0;出錯(cuò):-1(2)互斥操作函數(shù)int pthread_mutex_lock(pthread_mutex_t* mutex; /上鎖int pthread_mutex_trylock

3、(pthread_mutex_t* mutex; /只有在互斥被鎖住的情況下才阻塞int pthread_mutex_unlock (pthread_mutex_t* mutex; /解鎖int pthread_mutex_destroy (pthread_mutex_t* mutex; /清除互斥鎖函數(shù)傳入值:mutex:互斥鎖。函數(shù)返回值:成功:0;出錯(cuò):-1使用形式:pthread_mutex_t mutex;pthread_mutex_init (&mutex, NULL; /*定義*/.pthread_mutex_lock(&mutex; /*獲取互斥鎖*/. /*臨

4、界資源*/pthread_mutex_unlock(&mutex; /*釋放互斥鎖*/如果一個(gè)線程已經(jīng)給一個(gè)互斥量上鎖了,后來在操作的過程中又再次調(diào)用了該上鎖的操作,那么該線程將會(huì)無限阻塞在這個(gè)地方,從而導(dǎo)致死鎖。這就需要互斥量的屬性?;コ饬糠譃橄旅嫒N:1、快速型。這種類型也是默認(rèn)的類型。該線程的行為正如上面所說的。2、遞歸型。如果遇到我們上面所提到的死鎖情況,同一線程循環(huán)給互斥量上鎖,那么系統(tǒng)將會(huì)知道該上鎖行為來自同一線程,那么就會(huì)同意線程給該互斥量上鎖。3、錯(cuò)誤檢測(cè)型。如果該互斥量已經(jīng)被上鎖,那么后續(xù)的上鎖將會(huì)失敗而不會(huì)阻塞,pthread_mutex_lock(操作將會(huì)返回ED

5、EADLK。互斥量的屬性類型為pthread_mutexattr_t。聲明后調(diào)用pthread_mutexattr_init(來創(chuàng)建該互斥量。然后調(diào)用pthread_mutexattr_settype來設(shè)置屬性。格式如下:int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int kind;第一個(gè)參數(shù)attr,就是前面聲明的屬性變量;第二個(gè)參數(shù)kind,就是我們要設(shè)置的屬性類型。他有下面幾個(gè)選項(xiàng):PTHREAD_MUTEX_FAST_NPPTHREAD_MUTEX_RECURSIVE_NPPTHREAD_MUTEX_ERRORCHE

6、CK_NP下面給出一個(gè)使用屬性的簡(jiǎn)單過程:pthread_mutex_t mutex;pthread_mutexattr_t attr;pthread_mutexattr_init(&attr;pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE_NP;pthread_mutex_init(&mutex,&attr;pthread_mutex_destroy(&attr;前面我們提到在調(diào)用pthread_mutex_lock(的時(shí)候,如果此時(shí)mutex已經(jīng)被其他線程上鎖,那么該操作將會(huì)一直阻塞在這

7、個(gè)地方。如果我們此時(shí)不想一直阻塞在這個(gè)地方,那么可以調(diào)用下面函數(shù):pthread_mutex_trylock。如果此時(shí)互斥量沒有被上鎖,那么pthread_mutex_trylock將會(huì)返回0,并會(huì)對(duì)該互斥量上鎖。如果互斥量已經(jīng)被上鎖,那么會(huì)立刻返回EBUSY。二、條件變量需要的頭文件:pthread.h條件變量標(biāo)識(shí)符:pthread_cond_t1、互斥鎖的存在問題:互斥鎖一個(gè)明顯的缺點(diǎn)是它只有兩種狀態(tài):鎖定和非鎖定。設(shè)想一種簡(jiǎn)單情景:多個(gè)線程訪問同一個(gè)共享資源時(shí),并不知道何時(shí)應(yīng)該使用共享資源,如果在臨界區(qū)里加入判斷語(yǔ)句,或者可以有效,但一來效率不高,二來復(fù)雜環(huán)境下就難以編寫了,這是我們需要

8、一個(gè)結(jié)構(gòu),能在條件成立時(shí)觸發(fā)相應(yīng)線程,進(jìn)行變量修改和訪問。2、條件變量:條件變量通過允許線程阻塞和等待另一個(gè)線程發(fā)送信號(hào)的方法彌補(bǔ)了互斥鎖的不足,它常和互斥鎖一起使用。使用時(shí),條件變量被用來阻塞一個(gè)線程,當(dāng)條件不滿足時(shí),線程往往解開相應(yīng)的互斥鎖并等待條件發(fā)生變化。一旦其它的某個(gè)線程改變了條件變量,它將通知相應(yīng)的條件變量喚醒一個(gè)或多個(gè)正被此條件變量阻塞的線程。這些線程將重新鎖定互斥鎖并重新測(cè)試條件是否滿足。3、條件變量的相關(guān)函數(shù)pthread_cond_t cond = PTHREAD_COND_INITIALIZER; /條件變量結(jié)構(gòu)int pthread_cond_init(pthread_

9、cond_t *cond, pthread_condattr_t*cond_attr;int pthread_cond_signal(pthread_cond_t *cond;int pthread_cond_broadcast(pthread_cond_t *cond;int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex;int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,const struct timespec *ab

10、stime;int pthread_cond_destroy(pthread_cond_t *cond;詳細(xì)說明:(1創(chuàng)建和注銷條件變量和互斥鎖一樣,都有靜態(tài)動(dòng)態(tài)兩種創(chuàng)建方式a.靜態(tài)方式靜態(tài)方式使用PTHREAD_COND_INITIALIZER常量,如下:pthread_cond_t cond=PTHREAD_COND_INITIALIZERb.動(dòng)態(tài)方式動(dòng)態(tài)方式調(diào)用pthread_cond_init(函數(shù),API定義如下:int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr盡管POSIX標(biāo)準(zhǔn)中為條件

11、變量定義了屬性,但在LinuxThreads中沒有實(shí)現(xiàn),因此cond_attr值通常為NULL,且被忽略。注銷一個(gè)條件變量需要調(diào)用pthread_cond_destroy(,只有在沒有線程在該條件變量上等待的時(shí)候才能注銷這個(gè)條件變量,否則返回EBUSY。因?yàn)長(zhǎng)inux實(shí)現(xiàn)的條件變量沒有分配什么資源,所以注銷動(dòng)作只包括檢查是否有等待線程。API定義如下:int pthread_cond_destroy(pthread_cond_t *cond(2等待和激發(fā)a.等待int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex

12、/等待int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,const struct timespec *abstime /有時(shí)等待等待條件有兩種方式:無條件等待pthread_cond_wait(和計(jì)時(shí)等待pthread_cond_timedwait(,其中計(jì)時(shí)等待方式如果在給定時(shí)刻前條件沒有滿足,則返回ETIMEOUT,結(jié)束等待,其中abstime以與time(系統(tǒng)調(diào)用相同意義的絕對(duì)時(shí)間形式出現(xiàn),0表示格林尼治時(shí)間1970年1月1日0時(shí)0分0秒。無論哪種等待方式,都必須和一個(gè)互斥鎖配合,以防止多個(gè)線程

13、同時(shí)請(qǐng)求pthread_cond_wait((或 pthread_cond_timedwait(,下同)的競(jìng)爭(zhēng)條件(Race Condition)。mutex互斥鎖必須是普通鎖(PTHREAD_MUTEX_TIMED_NP)或者適應(yīng)鎖(PTHREAD_MUTEX_ADAPTIVE_NP),且在調(diào)用pthread_cond_wait(前必須由本線程加鎖(pthread_mutex_lock(),而在更新條件等待隊(duì)列以前,mutex保持鎖定狀態(tài),并在線程掛起進(jìn)入等待前解鎖。在條件滿足從而離開 pthread_cond_wait(之前,mutex將被重新加鎖,以與進(jìn)入pthread_cond_wai

14、t(前的加鎖動(dòng)作對(duì)應(yīng)。b.激發(fā)激發(fā)條件有兩種形式,pthread_cond_signal(激活一個(gè)等待該條件的線程,存在多個(gè)等待線程時(shí)按入隊(duì)順序激活其中一個(gè);而pthread_cond_broadcast(則激活所有等待線程。(3其他操作pthread_cond_wait (和pthread_cond_timedwait(都被實(shí)現(xiàn)為取消點(diǎn),因此,在該處等待的線程將立即重新運(yùn)行,在重新鎖定mutex后離開 pthread_cond_wait(,然后執(zhí)行取消動(dòng)作。也就是說如果pthread_cond_wait(被取消,mutex是保持鎖定狀態(tài)的,因而需要定義退出回調(diào)函數(shù)來為其解鎖。pthread_

15、cond_wait實(shí)際上可以看作是以下幾個(gè)動(dòng)作的合體:解鎖線程鎖;等待條件為true;加鎖線程鎖;使用形式:/ 線程一代碼pthread_mutex_lock(&mutex;if (條件滿足pthread_cond_signal(&cond;pthread_mutex_unlock(&mutex;/ 線程二代碼pthread_mutex_lock(&mutex;while (條件不滿足pthread_cond_wait(&cond, &mutex;pthread_mutex_unlock(&mutex;/*線程二中為什么使用while呢?

16、因?yàn)樵趐thread_cond_signal和pthread_cond_wait返回之間,有時(shí)間差,假設(shè)在這個(gè)時(shí)間差內(nèi),條件改變了,顯然需要重新檢查條件。也就是說在pthread_cond_wait被喚醒的時(shí)候可能該條件已經(jīng)不成立。*/三、信號(hào)量信號(hào)量其實(shí)就是一個(gè)計(jì)數(shù)器,也是一個(gè)整數(shù)。每一次調(diào)用wait操作將會(huì)使semaphore值減一,而如果semaphore值已經(jīng)為0,則wait操作將會(huì)阻塞。每一次調(diào)用post操作將會(huì)使semaphore值加一。需要的頭文件:semaphore.h信號(hào)量標(biāo)識(shí)符:sem_t主要函數(shù):(1sem_init功能:    &

17、#160;    用于創(chuàng)建一個(gè)信號(hào)量,并初始化信號(hào)量的值。函數(shù)原型:     int sem_init (sem_t* sem, int pshared, unsigned int value;函數(shù)傳入值:   sem:信號(hào)量。pshared:決定信號(hào)量能否在幾個(gè)進(jìn)程間共享。由于目前LINUX還沒有實(shí)現(xiàn)進(jìn)程間共享信息量,所以這個(gè)值只能取0。value:初始計(jì)算器函數(shù)返回值:   0:成功;-1:失敗。(2其他函數(shù)。/等待信號(hào)量int sem_wait (sem_t* sem;int s

18、em_trywait (sem_t* sem;/發(fā)送信號(hào)量int sem_post (sem_t* sem;/得到信號(hào)量值int sem_getvalue (sem_t* sem;/刪除信號(hào)量int sem_destroy (sem_t* sem;功能:sem_wait和sem_trywait相當(dāng)于P操作,它們都能將信號(hào)量的值減一,兩者的區(qū)別在于若信號(hào)量的值小于零時(shí),sem_wait將會(huì)阻塞進(jìn)程,而sem_trywait則會(huì)立即返回。sem_post相當(dāng)于V操作,它將信號(hào)量的值加一,同時(shí)發(fā)出喚醒的信號(hào)給等待的進(jìn)程(或線程)。sem_getvalue 得到信號(hào)量的值。sem_destroy 摧毀信號(hào)量。使用形

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(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)論