亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C > 正文

解析互斥量與條件變量的詳解

2020-02-24 14:27:03
字體:
來源:轉載
供稿:網友

在過程管理中,互斥變量和條件變量是必不可少的,任務間的調度幾乎是由互斥變量和條件變量控制的,互斥體的實現類似于進程信號量的實現,本文是武林技術頻道小編為大家整理的解析互斥量與條件變量的詳解,一起來看看吧!

一、互斥量

1. 初始化與銷毀:

???對于靜態分配的互斥量, 可以初始化為PTHREAD_MUTEX_INITIALIZER等價于pthread_mutex_init(…, NULL))調用pthread_mutex_init。

???對于動態分配的互斥量, 在申請內存(malloc)之后,通過pthread_mutex_init進行初始化, 并且在釋放內存(free)前需要調用pthread_mutex_destroy.

? ? int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t*restric attr);

? ? int pthread_mutex_destroy(pthread_mutex_t *mutex);

返回值:成功則返回0,出錯則返回錯誤編號.

說明:1、如果使用默認的屬性初始化互斥量,只需把attr設為NULL。

? ? ? ? ? ?2、銷毀一個互斥鎖即意味著釋放它所占用的資源,且要求鎖當前處于開放狀態。由于在Linux中,互斥鎖并不占用任何資源,因此 LinuxThreads中的pthread_mutex_destroy()除了檢查鎖狀態以外(鎖定狀態則返回EBUSY)沒有其他動作。

2. 互斥操作:

???對共享資源的訪問, 要對互斥量進行加鎖,如果互斥量已經上了鎖, 調用線程會阻塞,直到互斥量被解鎖。在完成了對共享資源的訪問后, 要對互斥量進行解鎖。

? ??int pthread_mutex_lock(pthread_mutex_t *mutex);? //P操作:請求資源(+1)

? ??int pthread_mutex_trylock(pthread_mutex_t *mutex);

? ??int pthread_mutex_unlock(pthread_mutex_t *mutex);//V操作:釋放資源(-1)

返回值:成功則返回0,出錯則返回錯誤編號.

說明:1、想給一個互斥量上鎖,我們調用pthread_mutex_lock。如果mutex已經上鎖,調用的線程將會被阻塞,直至信號量解鎖。

???????2、具體說一下trylock函數, 這個函數是非阻塞調用模式,也就是說, 如果互斥量沒被鎖住,trylock函數將把互斥量加鎖, 并獲得對共享資源的訪問權限;如果互斥量被鎖住了,trylock函數將不會阻塞等待而直接返回EBUSY, 表示共享資源處于忙狀態。

???????3、要解鎖一個信號量,我們調用phtread_mutex_unlock。

3. 死鎖、同步、與互斥的關系

3.1 死鎖:

???有時,可能需要同時訪問兩個資源。您可能正在使用其中的一個資源,隨后發現還需要另一個資源。如果兩個線程嘗試聲明這兩個資源,但是以不同的順序鎖定與這些資源相關聯的互斥鎖,則會出現問題。例如,如果兩個線程分別鎖定互斥鎖1 和互斥鎖 2,則每個線程嘗試鎖定另一個互斥鎖時,將會出現死鎖。下面的例子說明了可能的死鎖情況。

?

線程 1

線程 2

pthread_mutex_lock(&m1);

pthread_mutex_lock(&m2);

do something……

pthread_mutex_unlock(&m2);

pthread_mutex_unlock(&m1);

pthread_mutex_lock(&m2);

pthread_mutex_lock(&m1);

do something……

pthread_mutex_unlock(&m1);

pthread_mutex_unlock(&m2);


3.2 同步:??

?

線程 1

線程 2

pthread_mutex_lock(&m1);

do something……

pthread_mutex_unlock(&m2);

pthread_mutex_lock(&m2);

do something……

pthread_mutex_unlock(&m1);


3.3 互斥:?

?

線程 1

pthread_mutex_lock(&m1);

do something……//臨界區(Critical Section)

pthread_mutex_unlock(&m1);

?

4. 互斥量之前輩總結

? ? ? ?1.共享資源操作前一定要獲得鎖。

? ? ? ?2.完成操作以后一定要釋放鎖。

? ? ? ?3.盡量短時間地占用鎖。

? ? ? ?4.如果有多鎖, 如獲得順序是ABC連環扣,釋放順序也應該是ABC。

? ? ? ?5.線程錯誤返回時應該釋放它所獲得的鎖。

二、條件變量

1. 創建和注銷

??? 條件變量和互斥鎖一樣,都有靜態動態兩種創建方式

a.?靜態方式

??? 靜態方式使用PTHREAD_COND_INITIALIZER常量,如:?pthread_cond_t ?cond = PTHREAD_COND_INITIALIZER

b.?動態方式
???int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr)

??? 使用 cond_attr 指定的屬性初始化條件變量 cond,當 cond_attr NULL時,使用缺省的屬性。LinuxThreads實現條件變量不支持屬性,因此 cond_attr參數實際被忽略。
c.?注銷

??? int pthread_cond_destroy(pthread_cond_t *cond)

? ??注銷一個條件變量需要調用pthread_cond_destroy(),只有在沒有線程在該條件變量上等待的時候才能注銷這個條件變量,否則返回EBUSY。因為Linux實現的條件變量沒有分配什么資源,所以注銷動作只包括檢查是否有等待線程。

2. 等待和激發

2.1?等待

???int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
? ?這個函數POSIX線程信號發送系統的核心,也是最難以理解的部分,過程為:解鎖-wait-收到信號-加鎖-返回。

2.2?設置時間的等待

???int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, conststruct timespec *abstime)

??? pthread_cond_timedwait pthread_cond_wait一樣,自動解鎖互斥量及等待條件變量,但它還限定了等待時間。如果在 abstime指定的時間內 cond未觸發,互斥量 mutex被重新加鎖,并返回錯誤 ETIMEDOUT。abstime參數指定一個絕對時間,時間原點與 time gettimeofday相同:abstime = 0表示 1970 年 1 1 00:00:00 GMT。?

2.3?激發

??? int pthread_cond_signal(pthread_cond_t *cond);
??? int pthread_cond_broadcast(pthread_cond_t *cond);

??? 激發條件有兩種形式,pthread_cond_signal()激活一個等待該條件的線程,多個線程阻塞在此條件變量上時,哪一個線程被喚醒是由線程的調度策略所決定的;而pthread_cond_broadcast()激活所有等待線程,這些線程被喚醒后將再次競爭相應的互斥鎖。

???要注意的是,必須用保護條件變量的互斥鎖來保護激活函數,否則條件滿足信號有可能在測試條件和調用pthread_cond_wait()函數之間被發出,從而造成無限制的等待。?

三、互斥量與條件變量

? ??互斥量存在的問題:從本質上說互斥量就是一把鎖,互斥量串行執行,能確保每次只有一個線程訪問。互斥量是線程程序必需的工具,但它們并非萬能的。例如,如果線程正在輪詢等待共享數據內某個條件出現,那會發生什么呢?它可以重復對互斥對象鎖定和解鎖,每次都會檢查共享數據結構,以查找某個值。但這是在浪費時間和資源,而且這種繁忙查詢的效率非常低。同樣,在每次檢查之間讓線程短暫地進入睡眠,比如睡眠3s,但是因此線程代碼就無法最快作出響應。

? ??問題的解決:?條件變量通過允許線程阻塞和等待另一個線程發送信號的方法彌補了互斥鎖的不足,條件變量常和互斥鎖一起使用。使用時,條件變量被用來阻塞一個線程,當條件不滿足時,線程往往解開相應的互斥鎖并等待條件發生變化。一旦其它的某個線程改變了條件變量,它將通知相應的條件變量喚醒一個或多個正被此條件變量阻塞的線程。這些線程將重新鎖定互斥鎖并重新測試條件是否滿足。

四、線程管理相關代碼

?

//省略了線程互斥量以及條件變量的初始化
//線程管理:阻塞sec秒讀取線程信息
//三個參數分別為:線程信息、線程ID、超時秒數
bool ManagePthread_TimeReadSignal(PTHREAD_BUF *rbuf, PTHREAD_ID thread_num, int sec)
{
??? bool b_valid = false;
??? struct timespec to;
??? int err;
??? to.tv_sec = time(NULL) + sec;
??? to.tv_nsec = 0;

?//上鎖
??? pthread_mutex_lock(&managePthread.g_pthread_mutex[thread_num]);
?//超時sec秒阻塞等待,類似select
??? err = pthread_cond_timedwait(&managePthread.g_pthread_cond[thread_num], &managePthread.g_pthread_mutex[thread_num], &to);
??? if(err == ETIMEDOUT)
??? {
??????? pthread_mutex_unlock(&managePthread.g_pthread_mutex[thread_num]);
??????? return false;
??? }

?//獲取線程信息
??? if(managePthread.g_pthread_info[thread_num] == WRITE_FLAG)
??? {
??????? managePthread.g_pthread_info[thread_num] = READ_FLAG;
??????? memcpy((PTHREAD_BUF *)rbuf, (PTHREAD_BUF *)&managePthread.g_pthread_buf[thread_num], sizeof(PTHREAD_BUF));
??????? b_valid = true;
??? }

?//解鎖
??? pthread_mutex_unlock(&managePthread.g_pthread_mutex[thread_num]);
??? return b_valid;
}
//阻塞讀取線程信息
bool ManagePthread_ReadSignal(PTHREAD_BUF *rbuf, PTHREAD_ID thread_num, bool wait)
{
??? bool b_valid = false;
??? pthread_mutex_lock(&managePthread.g_pthread_mutex[thread_num]);
??? if(wait == true)
??????? pthread_cond_wait(&managePthread.g_pthread_cond[thread_num], &managePthread.g_pthread_mutex[thread_num]);
??? if(managePthread.g_pthread_info[thread_num] == WRITE_FLAG)
??? {
??????? managePthread.g_pthread_info[thread_num] = READ_FLAG;
??????? memcpy((PTHREAD_BUF *)rbuf, (PTHREAD_BUF *)&managePthread.g_pthread_buf[thread_num], sizeof(PTHREAD_BUF));
??????? b_valid = true;
??? }
??? pthread_mutex_unlock(&managePthread.g_pthread_mutex[thread_num]);
??? return b_valid;
}
//激活/發送線程信息
bool ManagePthread_SendSignal(PTHREAD_BUF *sbuf, PTHREAD_ID thread_num)
{
??? bool b_valid = false;
??? pthread_mutex_lock(&managePthread.g_pthread_mutex[thread_num]);
??? managePthread.g_pthread_info[thread_num] = WRITE_FLAG;
??? if(sbuf)
??? {
??????? memcpy((PTHREAD_BUF *)&managePthread.g_pthread_buf[thread_num], (PTHREAD_BUF *)sbuf, sizeof(PTHREAD_BUF));
??? }
??? pthread_mutex_unlock(&managePthread.g_pthread_mutex[thread_num]);
??? pthread_cond_signal(&managePthread.g_pthread_cond[thread_num]);
??? b_valid = true;
??? return b_valid;
}
//廣播
bool ManagePthread_BroadcastSignal(PTHREAD_BUF *sbuf, PTHREAD_ID thread_num)
{
??? bool b_valid = false;
??? pthread_mutex_lock(&managePthread.g_pthread_mutex[thread_num]);
??? managePthread.g_pthread_info[thread_num] = WRITE_FLAG;
??? memcpy((PTHREAD_BUF *)&managePthread.g_pthread_buf[thread_num], (PTHREAD_BUF *)sbuf, sizeof(PTHREAD_BUF));
??? pthread_mutex_unlock(&managePthread.g_pthread_mutex[thread_num]);
??? pthread_cond_broadcast(&managePthread.g_pthread_cond[thread_num]);
??? b_valid = true;
??? return b_valid;
}

以上就是關于解析互斥量與條件變量的詳解,介紹的很詳細了,如果你還想了解更多的知識,請隨時來武林技術頻道學習吧!

?

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美日韩成人免费| 91久久中文字幕| 久久人91精品久久久久久不卡| 国产精品老女人视频| 亚洲成人久久电影| 日韩中文字幕网| 国产午夜精品美女视频明星a级| 亚洲国产一区自拍| 久久久国产影院| 久久精品视频在线播放| 亚洲精品一区中文字幕乱码| 久久久av一区| 欧美激情久久久久久| 国产精品视频中文字幕91| 88国产精品欧美一区二区三区| 久久69精品久久久久久久电影好| 欧美视频精品一区| 国产精品a久久久久久| 欧美日韩ab片| 亚洲在线观看视频| 91国自产精品中文字幕亚洲| 欧美国产日韩中文字幕在线| 色七七影院综合| 欧美日韩中文字幕| 成人伊人精品色xxxx视频| 69av在线播放| 色偷偷偷亚洲综合网另类| 91麻豆国产精品| 精品五月天久久| 亚洲精品成人网| 欧美日韩成人在线视频| 国产精品激情av在线播放| 欧美成人剧情片在线观看| 欧美在线观看网站| 久久久久久一区二区三区| 亚洲最大的av网站| 91在线中文字幕| 欧美综合在线观看| 日本中文字幕久久看| 97精品久久久中文字幕免费| 精品国产91久久久久久老师| 国产精品欧美在线| 在线观看久久久久久| 精品高清美女精品国产区| 亚洲女人初尝黑人巨大| 日本久久中文字幕| 日韩精品视频在线播放| 国产成人拍精品视频午夜网站| 亚洲毛片在线观看| 国产成人啪精品视频免费网| 91超碰中文字幕久久精品| 欧美高清在线视频观看不卡| 欧美wwwwww| 国产91精品久久久久久| 亚洲人成电影在线| 欧美色另类天堂2015| 在线观看精品国产视频| 精品国产乱码久久久久久虫虫漫画| 日韩高清不卡av| 亚洲福利精品在线| 亚洲欧美激情在线视频| 日韩精品免费在线播放| 亚洲第一精品电影| 久久精品福利视频| 欧美日本高清一区| 国产午夜精品一区理论片飘花| 一区二区在线免费视频| 亚洲精品国产欧美| 亚洲一区二区三区sesese| 亚洲桃花岛网站| 欧美日韩免费观看中文| 91国产高清在线| 欧美一区二区三区四区在线| 在线视频国产日韩| 色小说视频一区| 在线成人激情视频| 久久久久久伊人| 欧美理论片在线观看| 视频在线观看一区二区| 国产亚洲欧美视频| 亚洲男女自偷自拍图片另类| 久久久久久国产| 日韩免费在线看| 亚洲精品视频在线观看视频| 欧美极品第一页| 国产精品男女猛烈高潮激情| 亚洲人成网站777色婷婷| 亚洲欧美日韩久久久久久| 久久精品国产亚洲一区二区| 亚洲自拍偷拍在线| 色视频www在线播放国产成人| 欧美一级电影久久| 日韩av在线精品| 日本免费一区二区三区视频观看| 国产精品视频网站| 欧美激情xxxx| 日产精品99久久久久久| 日韩av色综合| 欧洲日本亚洲国产区| 欧美在线激情网| 欧美精品videosex性欧美| 欲色天天网综合久久| 亚洲图片欧洲图片av| 在线视频中文亚洲| 日本欧美一二三区| 国产精品精品视频| 精品亚洲va在线va天堂资源站| 日韩精品视频免费在线观看| 久久久久久久影视| 亚洲毛片在线观看| 久久久久久久激情视频| 亚洲欧美在线第一页| 日韩暖暖在线视频| 国产在线一区二区三区| 国产一级揄自揄精品视频| 国产欧美日韩最新| 亚洲免费伊人电影在线观看av| 国产亚洲精品高潮| 日韩av在线直播| 亚洲天堂日韩电影| 精品久久久久久亚洲国产300| 国产日韩在线播放| 久久噜噜噜精品国产亚洲综合| 日韩av成人在线| 韩国三级电影久久久久久| 91热福利电影| 色悠悠久久久久| 国产日韩欧美中文在线播放| 国产精品一区二区三区成人| 日韩国产高清污视频在线观看| 欧美激情18p| 日韩专区在线播放| 久久久免费高清电视剧观看| 色狠狠久久aa北条麻妃| 欧美黄色三级网站| 亚洲精品日韩欧美| 91久久精品国产91性色| 久久精品99久久久香蕉| 自拍视频国产精品| 91精品在线观看视频| 欧美放荡办公室videos4k| 日韩女优人人人人射在线视频| 国产一区二区久久精品| 国产日韩欧美视频| 亚洲精品一区二区在线| 中文字幕亚洲情99在线| 韩剧1988免费观看全集| 91精品国产91久久久久福利| 久久精品国产一区二区三区| 欧美日韩免费看| 北条麻妃99精品青青久久| 日韩欧美视频一区二区三区| 川上优av一区二区线观看| 日韩精品在线观看网站| 国产精品黄视频| 亚洲日韩中文字幕| 欧美大片免费观看在线观看网站推荐| 国产精品福利在线| 在线亚洲男人天堂| 欧美猛交ⅹxxx乱大交视频| 国产97人人超碰caoprom| 91日本视频在线| 最新69国产成人精品视频免费| 国产成人精品免费久久久久|