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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux线程同步之条件变量

發布時間:2025/3/21 linux 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux线程同步之条件变量 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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

條件變量使我們可以睡眠等待某種條件出現。條件變量是利用線程間共享的全局變量進行同步的一種機制,主要包括兩個動作:一個線程等待"條件變量的條件成立"而掛起;另一個線程使"條件成立"(給出條件成立信號)。

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

使用條件變量之前要先進行初始化。可以在單個語句中生成和初始化一個條件變量如:pthread_cond_t my_condition=PTHREAD_COND_INITIALIZER;(用于進程間線程的通信)。可以利用函數pthread_cond_init動態初始化。

條件變量分為兩部分: 條件和變量. 條件本身是由互斥量保護的. 線程在改變條件狀態前先要鎖住互斥量. 它利用線程間共享的全局變量進行同步的一種機制。

相關的函數如下:

1?int?pthread_cond_init(pthread_cond_t?*cond,pthread_condattr_t?*cond_attr);????
2?int?pthread_cond_wait(pthread_cond_t?*cond,pthread_mutex_t?*mutex);
3?int?pthread_cond_timewait(pthread_cond_t?*cond,pthread_mutex?*mutex,const?timespec?*abstime);
4?int?pthread_cond_destroy(pthread_cond_t?*cond);?
5?int?pthread_cond_signal(pthread_cond_t?*cond);
6?int?pthread_cond_broadcast(pthread_cond_t?*cond);?//解除所有線程的阻塞

簡要說明:?????

(1)初始化.init()或者pthread_cond_t cond=PTHREAD_COND_INITIALIER;屬性置為NULL (2)等待條件成立.pthread_wait,pthread_timewait.wait()釋放鎖,并阻塞等待條件變量為真 timewait()設置等待時間,仍未signal,返回ETIMEOUT(加鎖保證只有一個線程wait) (3)激活條件變量:pthread_cond_signal,pthread_cond_broadcast(激活所有等待線程) (4)清除條件變量:destroy;無線程等待,否則返回EBUSY

詳細說明

1. 初始化:

??? 條件變量采用的數據類型是pthread_cond_t, 在使用之前必須要進行初始化, 這包括兩種方式:

  • 靜態: 可以把常量PTHREAD_COND_INITIALIZER給靜態分配的條件變量.
  • 動態: pthread_cond_init函數, 是釋放動態條件變量的內存空間之前, 要用pthread_cond_destroy對其進行清理.

#include <pthread.h>

int pthread_cond_init(pthread_cond_t *restrict cond, pthread_condattr_t *restrict attr);
int pthread_cond_destroy(pthread_cond_t *cond);

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

??? 當pthread_cond_init的attr參數為NULL時, 會創建一個默認屬性的條件變量; 非默認情況以后討論.

2. 等待條件:

#include <pthread.h>

int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restric mutex);
int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict timeout);

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

??? 這兩個函數分別是阻塞等待和超時等待.

??? 等待條件函數等待條件變為真, 傳遞給pthread_cond_wait的互斥量對條件進行保護, 調用者把鎖住的互斥量傳遞給函數. 函數把調用線程放到等待條件的線程列表上, 然后對互斥量解鎖, 這兩個操作是原子的. 這樣便關閉了條件檢查和線程進入休眠狀態等待條件改變這兩個操作之間的時間通道, 這樣線程就不會錯過條件的任何變化.

??? 當pthread_cond_wait返回時, 互斥量再次被鎖住.

3. 通知條件:

#include <pthread.h>

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

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

??? 這兩個函數用于通知線程條件已經滿足. 調用這兩個函數, 也稱向線程或條件發送信號. 必須注意, 一定要在改變條件狀態以后再給線程發送信號.

示例程序

#include <stdio.h> #include <pthread.h>pthread_mutex_t mutex; pthread_cond_t cond; void *thread1(void *arg) {pthread_cleanup_push(pthread_mutex_unlock, &mutex);//提供函數回調保護while (1) {printf("thread1 is running\n");pthread_mutex_lock(&mutex);pthread_cond_wait(&cond, &mutex);printf("thread1 applied the condition\n");pthread_mutex_unlock(&mutex);sleep(4);}pthread_cleanup_pop(0);}void *thread2(void *arg) {while (1) {printf("thread2 is running\n");pthread_mutex_lock(&mutex);pthread_cond_wait(&cond, &mutex);printf("thread2 applied the condition\n");pthread_mutex_unlock(&mutex);sleep(1);}}int main() {pthread_t thid1, thid2;printf("condition variable study!\n");pthread_mutex_init(&mutex, NULL);pthread_cond_init(&cond, NULL);pthread_create(&thid1, NULL, (void *) thread1, NULL);pthread_create(&thid2, NULL, (void *) thread2, NULL);do {pthread_cond_signal(&cond);} while (1);sleep(20);pthread_exit(0);return 0;}

條件變量與互斥鎖、信號量的區別

?????? 1.互斥鎖必須總是由給它上鎖的線程解鎖,信號量的掛出即不必由執行過它的等待操作的同一進程執行。一個線程可以等待某個給定信號燈,而另一個線程可以掛出該信號燈。

?????? 2.互斥鎖要么鎖住,要么被解開(二值狀態,類型二值信號量)。

?????? 3.由于信號量有一個與之關聯的狀態(它的計數值),信號量掛出操作總是被記住。然而當向一個條件變量發送信號時,如果沒有線程等待在該條件變量上,那么該信號將丟失。

?????? 4.互斥鎖是為了上鎖而設計的,條件變量是為了等待而設計的,信號燈即可用于上鎖,也可用于等待,因而可能導致更多的開銷和更高的復雜性。

參考:http://blog.csdn.net/dai_weitao/archive/2007/08/22/1754964.aspx

總結

以上是生活随笔為你收集整理的Linux线程同步之条件变量的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。