【C/C++多线程编程之八】pthread条件变量
多線程編程之條件變量
? ? ?Pthread是 POSIX threads 的簡(jiǎn)稱,是POSIX的線程標(biāo)準(zhǔn)。
? ? ? ??互斥機(jī)制,包括互斥量【C/C++多線程編程之六】pthread互斥量,信號(hào)量【C/C++多線程編程之七】pthread信號(hào)量,互斥能很好的處理共享資源訪問的協(xié)調(diào)問題,是多線程同步必不可少的機(jī)制。互斥機(jī)制也有其缺陷,當(dāng)線程在等待共享資源滿足某個(gè)條件,互斥機(jī)制下,必須不斷地加鎖和解鎖,其間查詢共享資源是否滿足條件,這將帶來巨大的消耗。
? ? ? ? 此時(shí),需要新的機(jī)制來解決這個(gè)問題。
? ? ? ?1.條件變量機(jī)制:
? ? ? ? 條件變量機(jī)制彌補(bǔ)了互斥機(jī)制的缺陷,允許一個(gè)線程向另一個(gè)線程發(fā)送信號(hào)(這意味著共享資源某種條件滿足時(shí),可以通過某個(gè)線程發(fā)信號(hào)的方式通知等待的線程),允許阻塞等待線程(當(dāng)線程等待共享資源某個(gè)條件時(shí),可讓該線程阻塞,等待其他線程發(fā)送信號(hào)通知)。
? ? ? ? 條件變量機(jī)制在處理等待共享資源滿足某個(gè)條件問題時(shí),具有非常高的效率,且空間消耗相比互斥機(jī)制也有優(yōu)勢(shì)。
? ??
? ? ? ??2.條件變量與互斥量:
? ? ? ?條件變量機(jī)制,所有等待一個(gè)條件變量的線程會(huì)形成一個(gè)隊(duì)列,這個(gè)隊(duì)列顯然是全局的共享隊(duì)列。當(dāng)線程進(jìn)入等待狀態(tài),將線程添加到隊(duì)列就需要使用互斥量,防止多個(gè)線程同時(shí)使用pthread_cond_wait,在調(diào)用pthread_cond_wait前加鎖互斥量,進(jìn)入阻塞前解鎖互斥量。這也解釋了pthread_cond_wait函數(shù)參數(shù)需要互斥量。
? ? ? ??3.條件變量基本函數(shù):
? ? ? ? ?#include <semaphore.h>
初始化條件變量:
? ? ? ??int?pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr) ;
? ? ? ? 該函數(shù)第一個(gè)參數(shù)為條件變量指針,第二個(gè)參數(shù)為條件變量屬性指針(一般設(shè)為NULL)。該函數(shù)按照條件變量屬性對(duì)條件變量進(jìn)程初始化。
無(wú)條件等待:
? ? ? ??int?pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
? ? ? ? 該函數(shù)第一個(gè)參數(shù)為條件變量指針,第二個(gè)為互斥量指針。該函數(shù)調(diào)用前,需本線程加鎖互斥量,加鎖狀態(tài)的時(shí)間內(nèi)函數(shù)完成線程加入等待隊(duì)列操作?,線程進(jìn)入等待前函數(shù)解鎖互斥量。在滿足條件離開pthread_cond_wait函數(shù)之前重新獲得互斥量并加鎖,因此,本線程之后需要再次解鎖互斥量。
通知一個(gè)線程:
? ? ? ??int?pthread_cond_signal(pthread_cond_t *cond);
? ? ? ? 該函數(shù)的參數(shù)為條件變量指針。該函數(shù)向隊(duì)列第一個(gè)等待線程發(fā)送信號(hào),解除這個(gè)線程的阻塞狀態(tài)。
通知所有線程:
? ? ? ??int?pthread_cond_broadcast(pthread_cond_t *cond);
? ? ? ? 該函數(shù)的參數(shù)為條件變量指針。該函數(shù)想隊(duì)列所有等待線程發(fā)送信號(hào),解除這些線程的阻塞狀態(tài)。
銷毀條件變量:
? ? ? ??int?pthread_cond_destroy(pthread_cond_t *cond);
? ? ? ? 該函數(shù)銷毀條件變量。
? ? ? ??4.牛刀小試:
? ? ? ? ?共享資源i,線程1對(duì)i進(jìn)行無(wú)限加1操作,并輸出所有非5倍數(shù)的i值。當(dāng)i的值為5的倍數(shù)時(shí),通過條件變量機(jī)制,通知線程2,線程2輸出此時(shí)的i值。
?
?
?
?
#include "pthread.h"
#include "sched.h"
#include "semaphore.h"
#include "stdio.h"
#include "windows.h"
?
#pragma comment(lib, "pthreadVC2.lib")???? //必須加上這句
?
pthread_t t1;?????????? //pthread_t變量t1,用于獲取線程1的ID
pthread_t t2;?????????? //pthread_t變量t2,用于獲取線程2的ID
??????
pthread_mutex_t mutex;
pthread_cond_t cond;
?
int i=0;??????????????? //共享資源
?
void * child1(void *arg)
{
while(1)
{
pthread_mutex_lock(&mutex);
?
i++;
if(i%5==0)
{
pthread_cond_signal(&cond);
}
else
{
printf("我是線程? 1? 打印的數(shù)都非5的倍數(shù):? %d \n",i);
}
?
pthread_mutex_unlock(&mutex);
Sleep(1000);
}
}?????
?
void *child2(void *arg)
{
??? while(1)
{
pthread_mutex_lock(&mutex);
?
printf("code before pthread_con_wait");
?
pthread_cond_wait(&cond,&mutex);?????? //獲得信號(hào)之前,會(huì)重新獲得互斥鎖
?
printf("我是線程? 2? 打印5的倍數(shù):? %d \n",i);
?
pthread_mutex_unlock(&mutex);????????? //需要在此處釋放互斥鎖
?
Sleep(1000);
}
}
?
int main(void)
{????????
pthread_cond_init(&cond,NULL);
pthread_mutex_init(&mutex,NULL);
?
pthread_create(&t1,NULL,child1,NULL);
pthread_create(&t2,NULL,child2,NULL);
?
Sleep(100000000);
?
return 0;
}
?
來自 <https://blog.csdn.net/lovecodeless/article/details/24929273>
總結(jié)
以上是生活随笔為你收集整理的【C/C++多线程编程之八】pthread条件变量的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2020年中国便利店发展报告
- 下一篇: 2020年生活服务业新业态和新职业从业报