Linux多線程編程怎么實(shí)現(xiàn)

引言
條件變量是利用線程間共享的全局變量進(jìn)行同步的一種機(jī)制,主要包括兩個(gè)動(dòng)作:一個(gè)線程等待條件變量的條件成立而掛起(此時(shí)不再占用cpu);另一個(gè)線程使條件成立(給出條件成立信號(hào))。為了防止競(jìng)爭(zhēng),條件變量的使用總是和一個(gè)互斥鎖結(jié)合在一起。

函數(shù)原型
1. 定義條件變量

#include?<pthread.h>  /*?定義兩個(gè)條件變量?*/ pthread_cond_t?cond_pro,?cond_con;</pthread.h>

2. 初始化和銷毀條件變量

#include?<pthread.h>  int?pthread_cond_init(pthread_cond_t?*restrict?cond,?const?pthread_condattr_t?*restrict?attr);int?pthread_cond_destroy(pthread_cond_t?*cond);?/*?初始化條件變量?*/ pthread_cond_init(&amp;cond_pro,?null); pthread_cond_init(&amp;cond_con,?null); /*?銷毀條件變量?*/ pthread_cond_destroy(&amp;cond_pro); pthread_cond_destroy(&amp;cond_pro);</pthread.h>

3. 等待和激發(fā)條件

#include?<pthread.h>  int?pthread_cond_wait(pthread_cond_t?*restrict?cond,?pthread_mutex_t?*restrict?mutex);  int?pthread_cond_broadcast(pthread_cond_t?*cond); int?pthread_cond_signal(pthread_cond_t?*cond); /*?等待條件?*/ /*?注意:pthread_cond_wait為阻塞函數(shù)。解開(kāi)鎖,再等待。等條件滿足時(shí),需要搶到鎖,才可以被喚醒*/?? pthread_cond_wait(&amp;cond_pro,&amp;mutex);?  /*?激發(fā)條件?*/ /*?所有因?yàn)椴粷M足條件的線程都會(huì)阻塞在條件變量cond_pro中的一個(gè)隊(duì)列中?*/ /*?以廣播方式,通知所有被阻塞的所有線程?*/ pthread_cond_broadcast(&amp;cond_pro); /*?以signal方式,只通知排在最前面的線程?*/ pthread_cond_signal(&amp;cond_pro);</pthread.h>

代碼

/************************************************************************* ??&gt;?file?name:?my_con.c ??&gt;?author:?krischou ??&gt;?mail:zhoujx0219@163.com? ??&gt;?created?time:?tue?26?aug?2014?10:24:29?am?cst ?************************************************************************/  #include?<stdio.h> #include?<stdlib.h> #include?<string.h> #include?<pthread.h> #include?<unistd.h> #define?cell?10 #define?flore?0  ?  int?i?=?0;?/*?所有線程共享的全局變量,此處假定至多遞增至10,最小減到0?*/  pthread_mutex_t?mutex;???????/*?定義互斥鎖?*/ pthread_cond_t?cond_pro,?cond_con;?/*?定義兩個(gè)條件變量?*/  /*?生產(chǎn)者線程?*/ void*?pro_handler(void?*arg) { ??pthread_detach(pthread_self());??/*?由系統(tǒng)回收線程資源,而非主線程回收資源?,此類情況主線程是個(gè)服務(wù)器,永久不會(huì)退出?*/ ?? ??while(1) ??{ ????pthread_mutex_lock(&amp;mutex); ????while(i?&gt;=?cell) ????{ ??????pthread_cond_wait(&amp;cond_pro,&amp;mutex);? ??????/*?continue是輪詢,此處是阻塞?*/ ??????/*?把鎖放開(kāi)再等?,第一個(gè)參數(shù)是結(jié)構(gòu)體指針,其中有成員存放被阻塞的函數(shù)?*/ ??????/*不占cpu*/ ??????/*?不滿足條件時(shí)才會(huì)等?,需要?jiǎng)e人告訴它,才能喚醒它*//*?當(dāng)它返回時(shí),鎖也要回來(lái)了*/ ????} ????i++; ????if(i?==?1) ????{ ??????/*?由空到不空,喚醒消費(fèi)者?*/ ??????pthread_cond_signal(&amp;cond_con);??/*不會(huì)立馬signal被阻塞的消費(fèi)者線程,因?yàn)槠溥€要等鎖搶回來(lái)*/ ????} ????printf("add?i:?%d?n",?i); ????pthread_mutex_unlock(&amp;mutex); ????sleep(rand()?%?5?+?1); ??} }  /*?消費(fèi)者線程?*/ void*?con_handler(void?*arg) { ??pthread_detach(pthread_self()); ??while(1) ??{ ????pthread_mutex_lock(&amp;mutex); ????while(i??0) ??{ ????pthread_create(arr?+?index,?null,?pro_handler,?null); ????index++; ????pro_cnt--; ??} ??while(con_cnt?&gt;?0) ??{ ????pthread_create(arr?+?index,?null,?con_handler,?null); ????index++; ????con_cnt--; ??} ??while(1); ??pthread_mutex_destroy(&amp;mutex); ??pthread_cond_destroy(&amp;cond_pro); ??pthread_cond_destroy(&amp;cond_con); ??return?0; }</unistd.h></pthread.h></string.h></stdlib.h></stdio.h>

注意
無(wú)論是在生產(chǎn)者線程,還是在消費(fèi)者線程中。標(biāo)記黃色部分的判斷條件必須用while。以生產(chǎn)者線程舉例,當(dāng)i>=cell時(shí),也就是i滿時(shí),此時(shí)執(zhí)行pthread_cond_wait(&cond_cno,&mutex); 該生產(chǎn)者線程被掛起。必須等到消費(fèi)者線程pthread_cond_signal(&cond_pro); 將其喚醒。但是消費(fèi)者將其signal還不夠,被掛其的生產(chǎn)者線程必須重新拿到鎖,才可以被激活。但是,由于在消費(fèi)者signal的同時(shí),生產(chǎn)者并不能立即搶到鎖,所以此時(shí)可能i值又改變變?yōu)榇笥诘扔?0了。因此必須用while。不然可能導(dǎo)致i>10。

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點(diǎn)贊13 分享