第一章 擴充套件 條件變數

2021-09-08 08:32:59 字數 4682 閱讀 9915

一、什麼是條件變數

與互斥鎖不同,條件變數是用來等待而不是用來上鎖的。條件變數用來自動阻塞乙個執行緒,直到某特殊情況發生為止。通常條件變數和互斥鎖同時使用

條件變數使我們可以睡眠等待某種條件出現。條件變數是利用執行緒間共享的全域性變數進行同步的一種機制,主要包括兩個動作:乙個執行緒等待

"條件變數的條件成立

"而掛起;另乙個執行緒使

"條件成立

"(給出條件成立訊號)。

條件的檢測是在互斥鎖的保護下進行的。如果乙個條件為假,乙個執行緒自動阻塞,並釋放等待狀態改變的互斥鎖。如果另乙個執行緒改變了條件,它發訊號給關聯的條件變數,喚醒乙個或多個等待它的執行緒,重新獲得互斥鎖,重新評價條件。如果兩程序共享可讀寫的記憶體,條件變數可以被用來實現這兩程序間的執行緒同步。

使用條件變數之前要先進行初始化。可以在單個語句中生成和初始化乙個條件變數如:

pthread_cond_t my_condition=pthread_cond_initializer;

(用於程序間執行緒的通訊)。

也可以利用函式

pthread_cond_init

動態初始化。

二、條件變數函式 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>

函式原形:

intpthread_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 timespectimespec_t;

3.名稱:

pthread_cond_signal/pthread_cond_broadcast

目標:

條件變數通知

標頭檔案:

#include < pthread.h>

函式原形:

intpthread_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

#include

#include

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)

void *thread1(void *junk)

}void *thread2(void *junk)

}程式建立了

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

源文件<

>

解惑:1. 為什麼cond要和mutex連用?

考慮有這樣的情況:

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);

是為了應對執行緒1在呼叫pthread_cond_wait()但執行緒1還沒有進入wait cond的狀態的時候(也就是說還沒有進入等待),此時執行緒2呼叫了 cond_singal 的情況(此時執行緒2就通知執行緒1 cond 條件已經滿足)。 如果不用mutex鎖的話,這個cond_singal就丟失了,也就是說執行緒1收不到該訊號,因為此時都還沒有程序wait 狀態。加了鎖的情況是,執行緒2必須等到 mutex 被釋放(也就是 pthread_cod_wait() 進入wait_cond狀態 並自動釋放mutex) 的時候才能呼叫cond_singal.

2. pthread_cond_wait() 和 pthread_cond_signal()和鎖的關係

當呼叫pthread_cond_wait()之後,呼叫該函式的執行緒進入睡眠,同時開啟mutex

當呼叫pthread_cond_signal()之後,呼叫該函式的執行緒開啟mutex

第一章 擴充套件 條件變數

一 什麼是條件變數 與互斥鎖不同,條件變數是用來等待而不是用來上鎖的。條件變數用來自動阻塞乙個執行緒,直到某特殊情況發生為止。通常條件變數和互斥鎖同時使用。條件變數使我們可以睡眠等待某種條件出現。條件變數是利用執行緒間共享的全域性變數進行同步的一種機制,主要包括兩個動作 乙個執行緒等待 條件變數的條...

python第一章筆記 第一章 基礎

參與除法的兩個數中有乙個數為浮點數,結果也為浮點數 如 1.0 2,1 2.0,1.0 2.0 python print 1.0 2 結果 0.5 print 1 2.0 結果 0.5 print 1.0 2.0 結果 0.5 整數 整數,計算結果的小數部分被截除,只保留整數部分 不會四捨五入 如 ...

第一章 緒論

1.16 void print descending int x,int y,int z 按從大到小順序輸出三個數 print descending 1.17 status fib int k,int m,int f 求k階斐波那契序列的第m項的值f gender char schoolname 校...