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

歡迎訪問 生活随笔!

生活随笔

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

linux

Linux 线程学习之条件变量

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

互斥鎖:用來上鎖。

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

?

函數介紹:

?

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函數之間;
沒有線程正在處在阻塞等待的狀態下。

總結

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

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