日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

信号量与条件变量的区别

發(fā)布時(shí)間:2025/4/5 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 信号量与条件变量的区别 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

注意信號(hào)量與條件變量的區(qū)別

信號(hào)量?jī)?nèi)容可見(jiàn):http://www.cnblogs.com/charlesblc/p/6142868.html 信號(hào)量、共享內(nèi)存,以及消息隊(duì)列等System V IPC三劍客主要關(guān)注進(jìn)程間通信; 而條件變量、互斥鎖,主要關(guān)注線程間通信。 下面內(nèi)容參考:http://blog.chinaunix.net/uid-27164517-id-3282242.html pthread_cond_wait指的是條件變量,總和一個(gè)互斥鎖結(jié)合使用。在調(diào)用pthread_cond_wait前要先獲取鎖。pthread_cond_wait函數(shù)執(zhí)行時(shí)先自動(dòng)釋放指定的鎖,然后等待條件變量的變化。在函數(shù)調(diào)用返回之前,自動(dòng)將指定的互斥量重新鎖住

int pthread_cond_signal(pthread_cond_t * cond);

pthread_cond_signal通過(guò)條件變量cond發(fā)送消息,若多個(gè)消息在等待,它只喚醒一個(gè)

pthread_cond_broadcast可以喚醒所有。調(diào)用pthread_cond_signal后要立刻釋放互斥鎖,因?yàn)閜thread_cond_wait的最后一步是要將指定的互斥量重新鎖住,如果pthread_cond_signal之后沒(méi)有釋放互斥鎖,pthread_cond_wait仍然要阻塞。 無(wú)論哪種等待方式,都必須和一個(gè)互斥鎖配合,以防止多個(gè)線程同時(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) 互斥鎖的類型,有以下幾種:PTHREAD_MUTEX_TIMED_NP,這是缺省值,也就是普通鎖。當(dāng)一個(gè)線程加鎖以后,其余請(qǐng)求鎖的線程將形成一個(gè)等待隊(duì)列,并在解鎖后按優(yōu)先級(jí)獲得鎖。這種鎖策略保證了資源分配的公平性。PTHREAD_MUTEX_RECURSIVE_NP,嵌套鎖,允許同一個(gè)線程對(duì)同一個(gè)鎖成功獲得多次,并通過(guò)多次unlock解鎖。如果是不同線程請(qǐng)求,則在加鎖線程解鎖時(shí)重新競(jìng)爭(zhēng)。PTHREAD_MUTEX_ERRORCHECK_NP,檢錯(cuò)鎖,如果同一個(gè)線程請(qǐng)求同一個(gè)鎖,則返回EDEADLK,否則與PTHREAD_MUTEX_TIMED_NP類型動(dòng)作相同。這樣就保證當(dāng)不允許多次加鎖時(shí)不會(huì)出現(xiàn)最簡(jiǎn)單情況下的死鎖。PTHREAD_MUTEX_ADAPTIVE_NP,適應(yīng)鎖,動(dòng)作最簡(jiǎn)單的鎖類型,僅等待解鎖后重新競(jìng)爭(zhēng)。

且在調(diào)用pthread_cond_wait()前必須由本線程加鎖 (pthread_mutex_lock()),而在更新條件等待隊(duì)列以前,mutex保持鎖定狀態(tài),并在線程掛起進(jìn)入等待前解鎖。在條件滿足從而離開(kāi) pthread_cond_wait()之前,mutex將被重新加鎖,以與進(jìn)入pthread_cond_wait()前的加鎖動(dòng)作對(duì)應(yīng)。 ?

激發(fā)條件有兩種形式,pthread_cond_signal()激活一個(gè)等待該條件的線程,存在多個(gè)等待線程時(shí)按入隊(duì)順序激活其中一個(gè);而pthread_cond_broadcast()則激活所有等待線程。

下面是另一處說(shuō)明:給出了函數(shù)運(yùn)行全過(guò)程。 為什么在喚醒線程后要重新mutex加鎖?

了解 pthread_cond_wait() 的作用非常重要 -- 它是 POSIX 線程信號(hào)發(fā)送系統(tǒng)的核心,也是最難以理解的部分。 首先,讓我們考慮以下情況:線程為查看已鏈接列表而鎖定了互斥對(duì)象,然而該列表恰巧是空的。這一特定線程什么也干不了 -- 其設(shè)計(jì)意圖是從列表中除去節(jié)點(diǎn),但是現(xiàn)在卻沒(méi)有節(jié)點(diǎn)。因此,它只能:

鎖定互斥對(duì)象時(shí),線程將調(diào)用 pthread_cond_wait(&mycond,&mymutex)。 pthread_cond_wait() 所做的第一件事就是同時(shí)對(duì)互斥對(duì)象解鎖(于是其它線程可以修改已鏈接列表),并等待條件 mycond 發(fā)生(這樣當(dāng) pthread_cond_wait() 接收到另一個(gè)線程的“信號(hào)”時(shí),它將蘇醒)。現(xiàn)在互斥對(duì)象已被解鎖,其它線程可以訪問(wèn)和修改已鏈接列表,可能還會(huì)添加項(xiàng)。 【要求解鎖并阻塞是一個(gè)原子操作】 此時(shí),pthread_cond_wait() 調(diào)用還未返回。對(duì)互斥對(duì)象解鎖會(huì)立即發(fā)生,但等待條件 mycond 通常是一個(gè)阻塞操作,這意味著線程將睡眠,在它蘇醒之前不會(huì)消耗 CPU 周期。這正是我們期待發(fā)生的情況。線程將一直睡眠,直到特定條件發(fā)生,在這期間不會(huì)發(fā)生任何浪費(fèi) CPU 時(shí)間的繁忙查詢。從線程的角度來(lái)看,它只是在等待 pthread_cond_wait() 調(diào)用返回。 現(xiàn)在繼續(xù)說(shuō)明,假設(shè)另一個(gè)線程(稱作“2 號(hào)線程”)鎖定了 mymutex 并對(duì)已鏈接列表添加了一項(xiàng)。在對(duì)互斥對(duì)象解鎖之后,2 號(hào)線程會(huì)立即調(diào)用函數(shù) pthread_cond_broadcast(&mycond)。此操作之后,2 號(hào)線程將使所有等待 mycond 條件變量的線程立即蘇醒。這意味著第一個(gè)線程(仍處于 pthread_cond_wait() 調(diào)用中)現(xiàn)在將蘇醒。 是先解鎖還是先signal,各有優(yōu)缺點(diǎn),下文會(huì)分析。另外注意,signal的函數(shù)里面是不是解鎖加鎖的,跟wait不一樣。 現(xiàn)在,看一下第一個(gè)線程發(fā)生了什么。您可能會(huì)認(rèn)為在 2 號(hào)線程調(diào)用 pthread_cond_broadcast(&mymutex) 之后,1 號(hào)線程的 pthread_cond_wait() 會(huì)立即返回。不是那樣!實(shí)際上,pthread_cond_wait() 將執(zhí)行最后一個(gè)操作:重新鎖定 mymutex。一旦 pthread_cond_wait() 鎖定了互斥對(duì)象,那么它將返回并允許 1 號(hào)線程繼續(xù)執(zhí)行。那時(shí),它可以馬上檢查列表,查看它所感興趣的更改。實(shí)際上,一般是先解鎖。 來(lái)看一個(gè)例子: In Thread1: pthread_mutex_lock(&m_mutex); pthread_cond_wait(&m_cond,&m_mutex); pthread_mutex_unlock(&m_mutex); In Thread2: pthread_mutex_lock(&m_mutex); pthread_cond_signal(&m_cond); pthread_mutex_unlock(&m_mutex);

?

為什么要與pthread_mutex 一起使用呢?

這是為了應(yīng)對(duì) 線程1在調(diào)用pthread_cond_wait()但線程1還沒(méi)有進(jìn)入wait cond的狀態(tài)的時(shí)候,此時(shí)線程2調(diào)用了 cond_singal 的情況。 如果不用mutex鎖的話,這個(gè)cond_singal就丟失了。加了鎖的情況是,線程2必須等到 mutex 被釋放(也就是 pthread_cod_wait() 釋放鎖并進(jìn)入wait_cond狀態(tài) ,此時(shí)線程2上鎖) 的時(shí)候才能調(diào)用cond_singal.

pthread_cond_signal即可以放在pthread_mutex_lock和pthread_mutex_unlock之間,也可以放在pthread_mutex_lock和pthread_mutex_unlock之后,但是各有有缺點(diǎn)。

之間:
pthread_mutex_lock
? ? xxxxxxx
pthread_cond_signal
pthread_mutex_unlock 缺點(diǎn):在某下線程的實(shí)現(xiàn)中,會(huì)造成等待線程從內(nèi)核中喚醒(由于cond_signal)然后又回到內(nèi)核空間(因?yàn)閏ond_wait返回后會(huì)有原子加鎖的 行為)(注:意思是說(shuō)這時(shí)候signal的線程還沒(méi)有unlock,所以wait的線程加鎖會(huì)導(dǎo)致堵塞,并進(jìn)入內(nèi)核),所以一來(lái)一回會(huì)有性能的問(wèn)題。但是在LinuxThreads或者NPTL里面,就不會(huì)有這個(gè)問(wèn)題,因?yàn)樵贚inux 線程中,有兩個(gè)隊(duì)列,分別是cond_wait隊(duì)列和mutex_lock隊(duì)列, cond_signal只是讓線程從cond_wait隊(duì)列移到mutex_lock隊(duì)列,而不用返回到用戶空間,不會(huì)有性能的損耗。
所以在Linux中推薦使用這種模式。 之后:
pthread_mutex_lock
? ? xxxxxxx
pthread_mutex_unlock
pthread_cond_signal
優(yōu)點(diǎn):不會(huì)出現(xiàn)之前說(shuō)的那個(gè)潛在的性能損耗,因?yàn)樵趕ignal之前就已經(jīng)釋放鎖了
缺點(diǎn):如果unlock和signal之前,有個(gè)低優(yōu)先級(jí)的線程正在mutex上等待的話,那么這個(gè)低優(yōu)先級(jí)的線程就會(huì)搶占高優(yōu)先級(jí)的線程(cond_wait的線程),而這在上面的放中間的模式下是不會(huì)出現(xiàn)的。

總結(jié)

以上是生活随笔為你收集整理的信号量与条件变量的区别的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。