多線程同步條件變量

轉自:http://blog.csdn.net/hongmy525/article/details/5194006  謝謝博主,我也搞明白怎麼樣條件變量了。

最近看《UNIX環境高級編程》多線程同步,看到他舉例說條件變量pthread_cond_t怎麼用,

愣是沒有看懂,只好在網上找了份代碼,跑了跑,才弄明白

#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,thread1,(void *)NULL);/*創建進程t_a*/
    pthread_create(&t_b,NULL,thread2,(void *)NULL); /*創建進程t_b*/
    pthread_join(t_a, NULL);/*等待進程t_a結束*/
    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<=6;i++)
    {
        pthread_mutex_lock(&mutex);/*鎖住互斥量*/
		printf("thread1: lock %d/n", __LINE__);
        if(i%3==0){
			printf("thread1:signal 1  %d/n", __LINE__);
            pthread_cond_signal(&cond);/*條件改變,發送信號,通知t_b進程*/
			printf("thread1:signal 2  %d/n", __LINE__);
			sleep(1);
		}
        pthread_mutex_unlock(&mutex);/*解鎖互斥量*/
		printf("thread1: unlock %d/n/n", __LINE__);
		sleep(1);
	}
}
void *thread2(void *junk)
{
    while(i<6)
    {
        pthread_mutex_lock(&mutex);
		printf("thread2: lock %d/n", __LINE__);
		if(i%3!=0){
			printf("thread2: wait 1  %d/n", __LINE__);
            pthread_cond_wait(&cond,&mutex);/*解鎖mutex,並等待cond改變*/
			printf("thread2: wait 2  %d/n", __LINE__);
		}
        pthread_mutex_unlock(&mutex);
		printf("thread2: unlock %d/n/n", __LINE__);
		sleep(1);
	}
}

編譯:

[X61@horizon threads]$ gcc thread_cond.c -lpthread -o tcd

 

以下是程序運行結果:

[X61@horizon threads]$ ./tcd 
thread1: lock 30
thread1: unlock 40

thread2: lock 52
thread2: wait 1  55
thread1: lock 30
thread1: unlock 40

thread1: lock 30
thread1:signal 1  33
thread1:signal 2  35
thread1: unlock 40

thread2: wait 2  57
thread2: unlock 61

thread1: lock 30
thread1: unlock 40

thread2: lock 52
thread2: wait 1  55
thread1: lock 30
thread1: unlock 40

thread1: lock 30
thread1:signal 1  33
thread1:signal 2  35
thread1: unlock 40

thread2: wait 2  57
thread2: unlock 61

 

這裏的兩個關鍵函數就在pthread_cond_wait和pthread_cond_signal函數。

本例中:

線程一先執行,獲得mutex鎖,打印,然後釋放mutex鎖,然後阻塞自己1秒。

線程二此時和線程一應該是併發的執行
 ,這裏是一個要點,爲什麼說是線程此時是併發的執行,因爲此時不做任何干涉的話,是沒有辦法確定是線程一先獲得執行還是線程二先獲得執行,到底那個線程先獲得執行,取決於操作系統的調度,想刻意的讓線程2先執行,可以讓線程2一出來,先sleep一秒。
這裏併發執行的情況是,線程一先進入循環,然後獲得鎖,此時估計線程二執行,阻塞在
pthread_mutex_lock(&mutex);
這行語句中,直到線程1釋放mutex鎖
pthread_mutex_unlock(&mutex);/*解鎖互斥量*/
然後線程二得已執行,獲取metux鎖,滿足if條件,到pthread_cond_wait (&cond,&mutex);/*等待*/
這裏的線程二阻塞,不僅僅是等待cond變量發生改變,同時釋放mutex鎖 ,因爲當時看書沒有注意,所以這裏卡了很久。
mutex鎖釋放後,線程1終於獲得了mutex鎖,得已繼續運行,當線程1的if(i%3==0)的條件滿足後,通過pthread_cond_signal發送信號,告訴等待cond的變量的線程(這個情景中是線程二),cond條件變量已經發生了改變。

不過此時線程二並沒有立即得到運行 ,因爲線程二還在等待mutex鎖的釋放,所以線程一繼續往下走,直到線程一釋放mutex鎖,線程二才能停止等待,打印語句,然後往下走通過pthread_mutex_unlock(&mutex)釋放mutex鎖,進入下一個循環。


發佈了13 篇原創文章 · 獲贊 4 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章