linux 線程學習之條件變量

http://blog.csdn.net/hemmanhui/article/details/4417433

互斥鎖:用來上鎖。

條件變量:用來等待,當條件變量用來自動阻塞一個線程,直到某特殊情況發生為止。通常條件變量和互斥鎖同時使用。

?

函數介紹:

?

1.

名稱:

pthread_cond_init

目標:

條件變量初始化

頭文件:

#include < pthread.h>

函數原形:

int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);

參數:

cptr??條件變量

attr??條件變量屬性

返回值:

成功返回0,出錯返回錯誤編號。

?????

?

?

?

?

?

?

?

?

??pthread_cond_init函數可以用來初始化一個條件變量。他使用變量attr所指定的屬性來初始化一個條件變量,如果參數attr為空,那么它將使用缺省的屬性來設置所指定的條件變量。

?

2.

名稱:

pthread_cond_destroy

目標:

條件變量摧毀

頭文件:

#include < pthread.h>

函數原形:

int pthread_cond_destroy(pthread_cond_t *cond);

參數:

cptr??條件變量

返回值:

成功返回0,出錯返回錯誤編號。

??????

?

?

?

?

?

?

?pthread_cond_destroy函數可以用來摧毀所指定的條件變量,同時將會釋放所給它分配的資源。調用該函數的進程也并不要求等待在參數所指定的條件變量上。

?

3.

名稱:

pthread_cond_wait/pthread_cond_timedwait

目標:

條件變量等待

頭文件:

#include < pthread.h>

函數原形:

int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex);

int pthread_cond_timedwait(pthread_cond_t *cond,pthread_mutex_t mytex,const struct timespec *abstime);

參數:

cond?條件變量

mutex?互斥鎖

返回值:

成功返回0,出錯返回錯誤編號。

??????

?

?

?

?

?

?

?

?

?

?第一個參數*cond是指向一個條件變量的指針。第二個參數*mutex則是對相關的互斥鎖的指針。函數pthread_cond_timedwait函數類型與函數pthread_cond_wait,區別在于,如果達到或是超過所引用的參數*abstime,它將結束并返回錯誤ETIME.pthread_cond_timedwait函數的參數*abstime指向一個timespec結構。該結構如下:

typedef struct timespec{

???????time_t tv_sec;

???????long tv_nsex;

}timespec_t;

?

3.

名稱:

pthread_cond_signal/pthread_cond_broadcast

目標:

條件變量通知

頭文件:

#include < pthread.h>

函數原形:

int pthread_cond_signal(pthread_cond_t *cond);

int pthread_cond_broadcast(pthread_cond_t *cond);

參數:

cond?條件變量

返回值:

成功返回0,出錯返回錯誤編號。

??????

?

?

?

?

?

?

?

?參數*cond是對類型為pthread_cond_t?的一個條件變量的指針。當調用pthread_cond_signal時一個在相同條件變量上阻塞的線程將被解鎖。如果同時有多個線程阻塞,則由調度策略確定接收通知的線程。如果調用pthread_cond_broadcast,則將通知阻塞在這個條件變量上的所有線程。一旦被喚醒,線程仍然會要求互斥鎖。如果當前沒有線程等待通知,則上面兩種調用實際上成為一個空操作。如果參數*cond指向非法地址,則返回值EINVAL。

?

下面是一個簡單的例子,我們可以從程序的運行來了解條件變量的作用。

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;/*
初始化互斥鎖*/
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;/*
初始化條件變量*/

void *thread1(void *);
void *thread2(void *);

int i=1;
int main(void)
{
????
pthread_t t_a;
????pthread_t t_b;

????pthread_create(&t_a,NULL,thread2,(void *)NULL);/*創建進程t_a*/
????
pthread_create(&t_b,NULL,thread1,(void *)NULL); /*創建進程t_b*/
????
pthread_join(t_b, NULL);/*等待進程t_b結束*/
????
pthread_mutex_destroy(&mutex);
????pthread_cond_destroy(&cond);
????exit(0);
}

void *thread1(void *junk)
{
????for(i=1;i<=9;i++)?
????{
? ??????pthread_mutex_lock(&mutex);/*鎖住互斥量*/
? ??????
if(i%3==0)
? ?? ????????pthread_cond_signal(&cond);/*條件改變,發送信號,通知t_b進程*/
? ??????else? ? ? ??
? ?? ????????printf("thead1:%d/n",i);
? ??????pthread_mutex_unlock(&mutex);/*解鎖互斥量*/

sleep(1);
}

}

void *thread2(void *junk)
{
????
while(i<9)
????{
? ??????pthread_mutex_lock(&mutex);

if(i%3!=0)
? ??????
????pthread_cond_wait(&cond,&mutex);/*等待*/
? ??????
printf("thread2:%d/n",i);
? ??????pthread_mutex_unlock(&mutex);

sleep(1);
}

}

程序創建了2個新線程使他們同步運行,實現進程t_b打印20以內3的倍數,t_a打印其他的數,程序開始線程t_b不滿足條件等待,線程t_a運行使a循環加1并打印。直到i為3的倍數時,線程t_a發送信號通知進程t_b,這時t_b滿足條件,打印i值。

下面是運行結果:

#cc –lpthread –o cond cond.c

#./cond

thread1:1

thread1:2

thread2:3

thread1:4

thread1:5

thread2:6

thread1:7

thread1:8

thread2:9

?

?

備注:

?pthread_cond_wait 執行的流程首先將這個mutex解鎖, 然后等待條件變量被喚醒, 如果沒有被喚醒, 該線程將一直休眠, 也就是說, 該線程將一直阻塞在這個pthread_cond_wait調用中, 而當此線程被喚醒時, 將自動將這個mutex加鎖,然后再進行條件變量判斷(原因是“驚群效應”,如果是多個線程都在等待這個條件,而同時只能有一個線程進行處理,此時就必須要再次條件判斷,以使只有一個線程進入臨界區處理。),如果滿足,則線程繼續執行,最后解鎖,

?

也就是說pthread_cond_wait實際上可以看作是以下幾個動作的合體:
解鎖線程鎖
等待線程喚醒,并且條件為true
加鎖線程鎖.


?pthread_cond_signal僅僅負責喚醒正在阻塞在同一條件變量上的一個線程,如果存在多個線程,系統自動根據調度策略決定喚醒其中的一個線程,在多處理器上,該函數是可能同時喚醒多個線程,同時該函數與鎖操作無關,解鎖是由pthread_mutex_unlock(&mutex)完成

?

?

喚醒丟失問題?
在線程并沒有阻塞在條件變量上時,調用pthread_cond_signal或pthread_cond_broadcast函數可能會引起喚醒丟失問題。

喚醒丟失往往會在下面的情況下發生:

一個線程調用pthread_cond_signal或pthread_cond_broadcast函數;?
另一個線程正處在測試條件變量和調用pthread_cond_wait函數之間;?
沒有線程正在處在阻塞等待的狀態下。

?


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/384015.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/384015.shtml
英文地址,請注明出處:http://en.pswp.cn/news/384015.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

UVa455

【題目描述】 傳送門 【題目分析】 就是一個簡單的暴力&#xff0c;只是需要注意輸出格式比較毒瘤。 【AC代碼】 #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<iostream> #include<cmath> #i…

網絡相關基礎概念

一. 相關基礎概念 1.計算機網絡的特點 (1)連通性:計算機網絡使得上網的用戶都能夠彼此相連, 好像用戶的計算機可以直接相連 ????(2)資源共享:資源共享可以是信息共享, 軟件共享, 硬件共享等等. 由于網絡的存在, 使得用戶感覺資源就在自己身邊 2. 網絡 網絡是由若干結點和…

linux線程同步(2)-條件變量

https://www.cnblogs.com/yuuyuu/p/5140875.html linux線程同步(2)-條件變量 一.概述 上一篇&#xff0c;介紹了互斥量。條件變量與互斥量不同&#xff0c;互斥量是防止多線程同時訪問共享的互斥變量來保護臨界區。條件變量…

UVa227

【題目描述】 傳送門 【題目分析】 題目的意思很簡單&#xff0c;只是輸入輸出很毒瘤&#xff0c;我一開始用的fgets然后用scanf(" ")吃掉所有的空格和換行&#xff0c;可是這樣有可能將迷宮的空格吃掉&#xff08;例如這個空格恰好在第一行第一列&#xff09;。 …

點對點數據鏈路層

數據鏈路層的主要功能將數據轉換為相應的比特流使用的信道主要有點對點的信道方式(一對一的方式), 以及廣播的信道方式 一. 點對點信道的數據鏈路層 1. 數據鏈路和數據幀 鏈路就是從一個結點連接到相鄰結點的一段物理線路(有線或者無線), 期間不準有任何的交換結點, 因此兩臺…

UVa232

[題目描述] 傳送門 [題目分析] 簡單的模擬,注意細節 [AC代碼] #include<cstdio> #include<cstring> #include<algorithm> #include<climits> #include<cctype> #include<queue> #include<set>using namespace std;typedef long…

linux線程同步(1)-互斥量

http://www.cnblogs.com/yuuyuu/p/5140251.html 一.概述 互斥量是線程同步的一種機制&#xff0c;用來保護多線程的共享資源。同一時刻&#xff0c;只允許一個線程對臨界區進行訪問。 互斥量的工作流程&#xff1a;創建一個…

UVa1368

[題目描述] 傳送門 [題目分析] 乍一看好像有點復雜,稍微思考一下只需要找到每個位置中最多的堿基.如果相等的話優先輸出字典序小的. [AC代碼] #include<cstdio> #include<cstring> #include<algorithm> #include<climits> #include<cctype>…

linux線程同步(3)-讀寫鎖

http://www.cnblogs.com/yuuyuu/p/5143881.html 一.概述 讀寫鎖與互斥量的功能類似&#xff0c;對臨界區的共享資源進行保護&#xff01;互斥量一次只讓一個線程進入臨界區&#xff0c;讀寫鎖比它有更高的并行性。讀寫鎖有…

樹的相關筆試面試題

1. 樹的創建 已知一個先序遍歷數的結果用數組表示, 其中空節點用 null_node 表示, 要求創建出這棵樹. 同樣采用遞歸的思想, 先定義一個指針, 指向數組中的第一個元素, 然后給數組的第一個結點創建相應的結點, 然后指針后移, 遞歸創建根節點的左子樹, 遞歸創建根節點的右子樹, …

UVa202

[題目描述] 傳送門 [題目分析] 就是一個模擬,不過稍微有點小復雜,而且輸出格式有點小毒瘤. 不過只是RE了兩發,PE了一發就過了,還是很開心. 需要注意數組要開很大,可能循環節出現在很后. 每個輸出樣例應該輸出一個空行,最后面也應該有,不然會PE [AC代碼] #include<cst…

linux線程同步(5)-屏障

http://www.cnblogs.com/yuuyuu/p/5152560.html 一.概述 barrier(屏障)與互斥量&#xff0c;讀寫鎖&#xff0c;自旋鎖不同&#xff0c;它不是用來保護臨界區的。相反&#xff0c;它跟條件變量一樣&#xff0c;是用來協同多…

淺談軟件測試

一. 什么是軟件測試 軟件測試是一個過程或者一系列過程, 用來測試計算機代碼完成了其應該完成的功能, 不執行不該有的操作.或者說軟件測試是根據軟件開發各階段的功能和說明而精心設計的一批測試用例, 并根據測試用例運行程序, 以發現程序錯誤的過程. 二. 軟件測試的心理學和…

UVa10340

【題目描述】 傳送門 【題目分析】 求字串&#xff0c;最好還是處理母串&#xff0c;每次找到一個子串就加1&#xff0c;這樣處理不用處理細節 【AC代碼】 #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include&l…

淺析linux下的條件變量

一.條件變量 條件變量是用來等待線程而不是上鎖的&#xff0c;條件變量通常和互斥鎖一起使用。條件變量之所以要和互斥鎖一起使用&#xff0c;主要是因為互斥鎖的一個明顯的特點就是它只有兩種狀態&#xff1a;鎖定和非鎖定&#xff0c;而條件變量可以通過允許線程阻塞和等待另…

UVa1587

【題目描述】 傳送門 【題目分析】 剛開始想簡單了&#xff0c;認為只要相對的面相等就可以了。然后發現三個不同方向的面的邊應該有相等的關系&#xff0c;即如果兩個面公用一條邊&#xff0c;那么這兩個面的另外兩條邊就是另一個面的兩條邊。而且這三個量里面肯定有一個最…

Linux多線程與同步

https://www.cnblogs.com/freedomabcd/p/7774743.html 典型的UNIX系統都支持一個進程創建多個線程(thread)。在Linux進程基礎中提到&#xff0c;Linux以進程為單位組織操作&#xff0c;Linux中的線程也都基于進程。盡管實現方式有異于其它的UNIX系統&#xff0c;但Linux的多線程…

內存管理(二)

頁面置換算法 當發生缺頁中斷的時候, 系統會在內存中選擇一個頁面將其換出內存, 而當換出內存的時候如果該頁面的內容在內存中發生修改,則必須將該新數據重新寫回到磁盤, 然后再將需要換進的數據覆蓋掉原來的數據, 而當該數據在內存中沒有被修改的時候, 此時就直接用需要換進的…

兩個棧實現一個隊列/兩個隊列實現一個棧

http://blog.csdn.net/sinat_30472685/article/details/70157227 1兩個棧實現一個隊列 1.原理分析&#xff1a; 隊列的主要操作有兩個&#xff1a;入隊操作和出隊操作&#xff0c;出隊時從隊頭出&#xff0c;入隊是從隊尾插入&#xff0c;入隊的操作和入棧的操作類似&#xff0…

UVa1588

【題目描述】 傳送門 【題目分析】 剛開始想了一會沒有想到什么很好的算法&#xff0c;看到了長度最多為100&#xff0c;就知道自己想的沒有什么意義了&#xff0c;直接暴力&#xff0c;把每一種填法都試一下就知道了。適當剪枝一下&#xff08;一個簡單的樂觀函數&#xff…