近期學習了線程等待和激活的相關知識。
先介紹幾個api:
pthread_cond_t表示多線程的條件變量,用於控制線程等待和就緒的條件。
一:條件變量的初始化:
條件變量和互斥鎖一樣,都有靜態動態兩種創建方式,
靜態方式使用PTHREAD_COND_INITIALIZER常量初始化。
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
動態方式初始化:
1 首先要new或者malloc一個pthread_cond_t類型變量,
用完后記得delete或者free掉。
2
使用pthread_cond_wait方式如下:
pthread _mutex_lock(&mutex)
while或if(線程執行的條件是否成立)
pthread_cond_wait(&cond, &mutex);
線程執行
pthread_mutex_unlock(&mutex);
對於這點apue給出的解釋:The mutex passed to pthread_cond_wait protects the condition.The caller passes it locked to
the function, which then atomically places the calling thread on the list of threads waiting for the condition and unlocks
the mutex. This closes the window between the time that the condition is checked and the time that the
thread goes to sleep waiting for the condition to change, so that the thread doesn't miss a change in the condition.
When pthread_cond_wait returns, the mutex is again locked.
1,線程放在等待隊列上,解鎖
2,等待 pthread_cond_signal或者pthread_cond_broadcast信號之后去競爭鎖
3,若競爭到互斥索則加鎖。
使用流程
等待線程:
pthread_mutex_lock(&mutex);
if(條件不滿足)
pthread_cond_wait(&cond, &mutex);
//處理共享資源
pthread_mutex_unlock(&mutex);
激活線程:
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
下面寫了一個例子
#include <pthread.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <iostream> using namespace std; int count = 0; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond = PTHREAD_COND_INITIALIZER; //該函數增加count數值 void * creator(void * arg) { cout << "creator add lock" << endl; pthread_mutex_lock(&mutex); count ++; cout << "in creator count is : " << count << endl; //條件滿足時發送信號 if(count > 0) { pthread_cond_signal(&cond); } cout << "creator release lock" << endl; pthread_mutex_unlock(&mutex); return NULL; } //該函數減少count數值 void * consumer(void * arg) { cout << "consumer add lock" << endl; pthread_mutex_lock(&mutex); //當條件不滿足時等待 while(count <= 0) //防止虛假喚醒 { cout << "begin wait" << endl; pthread_cond_wait(&cond,&mutex); cout << "end wait" << endl; } count --; cout << "in consumer count is " << count << endl; pthread_mutex_unlock(&mutex); cout << "consumer release lock" << endl; return NULL; } int main() { //兩個線程,一個生產者線程一個消費者線程 pthread_t createthread,consumethread; pthread_create(&consumethread, NULL, consumer, NULL);
sleep(2); pthread_create(&createthread, NULL, creator, NULL); //主進程等待兩個線程結束 pthread_join(createthread, NULL); pthread_join(consumethread, NULL); return 0; }

void * creator(void * arg) { int i = 0; while(i<300) { i++; cout << "creator add lock" << endl; pthread_mutex_lock(&mutex); count ++; cout << "in creator count is : " << count << endl; if(count > 0) { pthread_cond_signal(&cond); } cout << "creator release lock" << endl; pthread_mutex_unlock(&mutex); } return NULL; } void * consumer(void * arg) { int i = 0; while(i < 100) { i++; cout << "consumer add lock" << endl; pthread_mutex_lock(&mutex); while(count <= 0) //防止虛假喚醒 { cout << "begin wait" << endl; pthread_cond_wait(&cond,&mutex); cout << "end wait" << endl; } count --; cout << "in consumer count is " << count << endl; pthread_mutex_unlock(&mutex); cout << "consumer release lock" << endl; } return NULL; } int main() { pthread_t createthread[2],consumethread[3]; for(int i = 0; i < 3; i++) { pthread_create(&consumethread[i], NULL, consumer, NULL); } for(int i = 0; i < 2; i++) { pthread_create(&createthread[i], NULL, creator, NULL); } for(int i = 0; i < 2; i++) { pthread_join(createthread[i], NULL); } for(int i = 0; i < 3; i++) { pthread_join(consumethread[i], NULL); } return 0; }
截取一部分結果截圖,可以看出數字是連續變動的,而且
加鎖解鎖內數字才變動,說明我們對鎖和條件變量使用合理。
