關于線程間(jian)通信
時間:2018-09-21 來源(yuan):未(wei)知
多進(jin)程(cheng)和多線程(cheng)是系統執(zhi)行多任務機制的重要手段(duan),多任務同時進(jin)行自然少不了(le)相互(hu)之間的通信工作。下(xia)面先將線程(cheng)間的通信方式總(zong)結一下(xia),便于大家對比學(xue)習。
首先來說線程間的(de)(de)(de)通信。因為多個(ge)線程是共享(xiang)進程的(de)(de)(de)空(kong)間的(de)(de)(de),所(suo)以(yi)(yi)線程之間的(de)(de)(de)通信比較簡(jian)單(dan),主要是利用全(quan)局(ju)變量的(de)(de)(de)方法。全(quan)局(ju)變量對進程內的(de)(de)(de)的(de)(de)(de)所(suo)有(you)線程都是可見(jian)的(de)(de)(de),所(suo)以(yi)(yi)多個(ge)線程可以(yi)(yi)通過(guo)操作全(quan)局(ju)變量達(da)到相(xiang)互通信的(de)(de)(de)效果。但(dan)是這也存在一個(ge)問題,就是“資源”的(de)(de)(de)競爭。
這(zhe)里(li)所說的(de)(de)(de)資源指的(de)(de)(de)就是全(quan)局變量,正是因(yin)為這(zhe)種競爭(因(yin)為多線(xian)(xian)程(cheng)(cheng)是同時運行的(de)(de)(de),而(er)我們(men)(men)往往不(bu)(bu)會(hui)去(qu)控制線(xian)(xian)程(cheng)(cheng)運行的(de)(de)(de)順序,不(bu)(bu)然也(ye)不(bu)(bu)會(hui)用多線(xian)(xian)程(cheng)(cheng)了),導致可一(yi)些(xie)我們(men)(men)不(bu)(bu)愿見到(dao)的(de)(de)(de)結果,所以我們(men)(men)每(mei)個線(xian)(xian)程(cheng)(cheng)對全(quan)局變量的(de)(de)(de)操作都希(xi)望是原(yuan)子性的(de)(de)(de)。
為了解決這個問(wen)題(ti)在線程見引入(ru)了三種同步互斥機制(zhi),分別是(shi)信號量(liang)(liang),互斥鎖,條件變量(liang)(liang)。
具體的函數應(ying)用(yong)如(ru)下:
信號量
#include
int sem_init(sem_t *sem, int pshared, unsigned int value);
功能:信號量的初始(shi)化(hua)。
參數:
sem:就是(shi)信(xin)號(hao)量的(de)標(biao)識符
pshared: 0, 表示(shi)該信(xin)號量用(yong)于線程(cheng)之間的通信(xin)。
非0, 表示該信號量用于進程程之間的(de)通信。
value:非負的整數,就是信(xin)號(hao)量(liang)的初值。
如果(guo)為0, 表示沒有資源。
int sem_wait(sem_t *sem);
功能:阻塞申請(qing)信號(hao)量資(zi)源, 當信號(hao)量的(de)值等于0時,睡眠等待(dai)。
一旦申(shen)請成功,那么信號量的值(zhi)就會被減1.
參(can)數:sem:
int sem_trywait(sem_t *sem);
功能:非阻塞(sai)申請信號量(liang)資(zi)源,如果(guo)申請不到(dao)資(zi)源,那么該函數(shu)立刻返(fan)回。
int sem_post(sem_t *sem);
功能:釋放(fang)信號量資源
釋(shi)放(fang)成(cheng)功,信號(hao)量的值(zhi)加1.
int sem_getvalue(sem_t *sem, int *svalue);
功能(neng):獲得(de)當前信號量的值(zhi)。
參(can)數: sem, 指定要(yao)獲得的(de)信號量
svalue, 用(yong)于保存獲得的信號量的值。
int sem_destroy(sem_t *sem);
功(gong)能:銷毀無名(ming)信號量。
線程互斥鎖
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
功能:產生一(yi)把鎖
參數:mutex: 線程鎖的標識符
attr: 設置(zhi)線程鎖(suo)的(de)屬性,通常為NULL。
pthread_mutex_t lock;
pthread_mutex_init(&lock, NULL);
int pthread_mutex_lock(pthread_mutex_t *mutex);
功(gong)能:上鎖(suo), 阻塞等待,直(zhi)到能夠(gou)得到這(zhe)把鎖(suo)。
int pthread_mutex_unlock(pthread_mutex_t *mutex);
功能:解鎖。
int pthread_mutex_destroy(pthread_mutex_t *mutex);
功(gong)能:就是銷毀一把鎖。
條件變量:
int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
功能:初(chu)始化條件變量。
參數: cond: 條件(jian)變(bian)量的標識符
atrr:條(tiao)件(jian)變量(liang)的屬性,通(tong)常為NULL。
pthread_cond_t cond;
pthread_cond_init(&cond, NULL);
int pthread_cond_signal(pthread_cond_t *cond);
功能:就(jiu)是給一個需要該條件變量的(de)線程發送喚醒的(de)信(xin)號。
int pthread_cond_broadcast(pthread_cond_t *cond);
功能:給所(suo)有需(xu)要該條(tiao)件(jian)變量的線程都發(fa)送喚醒信號。
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
功(gong)能:就是(shi)導(dao)致線程睡眠在此函(han)數上,直(zhi)到有線程給(gei)它發送條件變量(liang)的喚醒信號。
參數:cond :需要改條件變量
mutex:就是(shi)一(yi)個鎖(suo)。
pthread_cond_wait():先將(jiang)鎖解(jie)開,然(ran)后進入睡眠,當被(bei)喚醒的時候(hou)需要重新加(jia)鎖(如果此時得不到鎖,那么繼續睡眠)。
int pthread_cond_destroy(pthread_cond_t *cond);
功能(neng):銷毀條件變量。
這(zhe)些函數的(de)具體用法在上課(ke)時(shi)候我們已經學過,不再(zai)做更為具體的(de)介紹(shao),希望同(tong)學們多加練習。這(zhe)里主要是總結(jie)下(xia)三者(zhe)的(de)應用。
這三種機制(zhi)中,信號(hao)量和條(tiao)件(jian)變(bian)量屬于一(yi)種阻塞(sai)通(tong)知(zhi)的機制(zhi)。采用(yong)阻塞(sai)的方法,讓一(yi)個進程中只(zhi)有(you)一(yi)個線程能(neng)“順利執行(xing)”,執行(xing)完畢后再(zai)通(tong)知(zhi)其(qi)他線程執行(xing)。而(er)互(hu)(hu)斥鎖是(shi)典(dian)型的互(hu)(hu)斥機制(zhi),對(dui)資(zi)源加以(yi)保護,在這期間不允許其(qi)他現場(chang)對(dui)保護的內(nei)容(rong)進行(xing)讀寫操作。通(tong)過信號(hao)量和條(tiao)件(jian)變(bian)量都可以(yi)實現經典(dian)的生產者消費(fei)者模(mo)式(shi)。

