Linux 條件變數

2022-08-30 01:33:13 字數 4749 閱讀 9686

條件變數

1. 問題

某些情況下,某些執行緒有這個需求:

僅當滿足某個特定條件時,才執行對應操作;

如果該條件不滿足,就阻塞該執行緒,一直等到對應的條件滿足才繼續執行。

解決方案:

當條件滿足時,使用訊號量喚醒對應執行緒,

當條件不滿足時,使用訊號量阻塞對應執行緒。

並用互斥量(互斥鎖)來保護對該條件的訪問。

linux提供了一種更方便的機制來解決該類問題:條件變數

使用方法

條件變數是一種特殊的「通知」,而不是指某個條件。

當特定的條件滿足時,就使用pthread_cond_signal傳送該通知(即傳送該條件)

即通知等待該條件的執行緒,它所等待的條件已經滿足了。

當特定的條件還不滿足時,就使用pthread_cond_wait來等待該通知(即等待該條件)

條件變數和互斥量結合使用:

(1) 等待」通知」的pthread_cond_wait和傳送「通知」的pthread_cond_signal,

這兩個呼叫的內部實現,需要使用互斥量,用來保護該條件變數。

(2) 用來判斷條件是否滿足的相關共享資源,也需要用該互斥量進行保護。

條件變數的使用介面

1) 條件變數的表示

型別:pthread_cond_t

2) 條件標量的初始化

編譯時初始化:

pthread_cond_t my_cond = pthread_cond_initializer;

執行時初始化:

pthread_cond_t my_cond;

pthread_cond_init(&my_cond, null);

/* 引數2為null, 表示該條件變數使用預設屬性 */

3) 等待條件標量

pthread_cond_wait

原型:int pthread_cond_wait (pthread_cond_t *cond,

pthread_mutex_t *mutex);

引數:cond, 條件變數

mutex, 該條件變數所使用的互斥量

pthread_cond_timedwait

原型: int pthread_cond_timedwait(pthread_cond_t *cond,

pthread_mutex_t *mutex,

const struct timespec *abstime);

功能:pthread_cond_wait的限時等待版本

引數:abstime, 是乙個絕對時間,即當前時間+超時時間

注意:當因等待該條件變數而使該執行緒阻塞時,隱含了乙個動作(對該互斥量進行解鎖)

當被喚醒時,即從該呼叫返回時,又隱含了乙個動作(對該互斥量進行加鎖)

4) 「傳送」該條件變數

即,通知(喚醒)等待該條件變數的執行緒。

如果沒有執行緒在等待該條件變數,則忽視該操作,無累積效應。(而多次執行v操作,將有「累積效應」)

pthread_cond_signal

原型: int pthread_cond_signal(pthread_cond_t *cond);

功能: 如果有多個執行緒都在等待該條件變數,

則,使用排程策略喚醒乙個執行緒,其餘執行緒繼續等待。

pthread_cond_broadcast

原型:int pthread_cond_broadcast(pthread_cond_t *cond);

功能:喚醒等待該條件變數的所有執行緒。

例項 生產者執行緒、消費者執行緒

最多可以同時存放buff_size個「產品」

每個產品用乙個整數表示。

即使用int buff[buff_size]存放所有產品。

當buff放滿時,不可以再生產。

當buff為空時,不可以再消費

分別調整生產者和消費者的速度,觀察輸出資訊。

main6.c

4. 建立兩個執行緒5

執行緒1接收使用者輸入

接收完成後,由執行緒2對該字串進行「加工」,即統計其長度,並列印輸出。

同步要求:

接收到使用者輸入後,才能統計字串長度。

使用者統計完成後,才能繼續接收使用者輸入。

main7.c

------------------------------

lock

if (判斷是否需要等待)

pthread_cond_wait(&cond, &lock)

work

unlock

-------------------------------

pthread_cond_signal(&cond);

_______________________________

thread1:

如果count > 0 就執行work()

否則,等待直到該條件滿足

pthread_mutex_lock(&lock);

if (!(count > 0))

pthread_mutex_unlock(&lock);

work();

執行緒2:

//count++;

pthread_mutex_lock(&lock);

if(count > 0)

void* handle_product(void *arg)

buff[pos_product] = i;

printf("product a productor(%d)\n", i);

pos_product++;

if (pos_product >= buff_size)

//pos_product = (pos_product+1)%buff_size;

pthread_cond_signal(&cond_consume);

pthread_mutex_unlock(&lock);

printf("product sleep begin.\n");

sleep(1);

printf("product sleep end.\n");

}}void* handle_consume(void *arg)

/* ¥」≤÷ø‚»°≥ˆ≤˙∆∑ */

val = buff[pos_consume];

printf("consume a product. val = %d\n", val);

/* –fi∏ƒø…œ˚∑—≤˙∆∑µƒœª÷√ */

pos_consume++;

if (pos_consume >= buff_size)

pthread_cond_signal(&cond_product);

pthread_mutex_unlock(&lock);

printf("consumer sleep...begin\n");

sleep(3);

printf("consumer sleep...end\n");

}}int main(void)

ret = pthread_create(&th_consume, 0, handle_consume, 0);

if (ret != 0)

pthread_join(th_product, 0);

pthread_join(th_consume, 0);

return

0;}

main7.c

#include 

#include

#include

#include

#include

#define buff_size 80

char buff[buff_size];

pthread_cond_t cond_input;

pthread_cond_t cond_work;

pthread_mutex_t lock;

void *hanle_input(void *arg)

else

bzero(buff, sizeof(buff));

ret = read(fd, buff, sizeof(buff));

if (ret == -1)

pthread_cond_signal(&cond_work);

pthread_mutex_unlock(&lock);}}

}}void *hanle_work(void *arg)

printf("you input %d characters\n", strlen(buff));

buff[0] = '\0';

pthread_cond_signal(&cond_input);

pthread_mutex_unlock(&lock);

}}static

void init_work(void)

int main(void)

ret = pthread_create(&th_work, 0, hanle_work, 0);

if (ret != 0)

pthread_join(th_input, 0);

pthread_join(th_work, 0);

return

0;}

linux條件變數

linux條件變數 條件變數 條件變數是利用執行緒間共享是全域性變數進行同步的一種機制。條件變數巨集觀上類似if語句,符合條件就能執行某段程式,否則只能等待條件成立。一 函式 pthread cond init函式 初始化條件變數 pthread cond wait函式 基於條件變數阻塞,無條件等待...

Linux 條件變數

當乙個執行緒互斥地訪問某個變數時,它可能發現在其它執行緒改變狀態之前,它什麼也做不了。例如 乙個執行緒訪問佇列時,發現隊列為空,它只能等待,直到其它執行緒將乙個節點新增到佇列中。類似這種情況就需要用到條件變數。同步概念與競態條件 同步 在保證資料安全的前提下,讓執行緒能夠按照某種特定的順序訪問臨界資...

Linux 條件變數

與互斥鎖不同,條件變數是用來等待而不是用來上鎖的,乙個條件變數對應乙個等待佇列。條件變數是利用執行緒間共享的全域性變數進行同步的一種機制,主要包括兩個動作 乙個執行緒等待 條件變數的條件成立 而掛起 另乙個執行緒使 條件成立 給出條件成立訊號 喚醒執行緒。1 pthread cond t cond ...