国产成人精品三级麻豆,色综合天天综合高清网,亚洲精品夜夜夜,国产成人综合在线女婷五月99播放,色婷婷色综合激情国产日韩

Hi,歡迎來(lái)到嵌入式培訓(xùn)高端品牌 - 華清遠(yuǎn)見教育科技集團(tuán)<北京總部官網(wǎng)>,專注嵌入式工程師培養(yǎng)15年!
當(dāng)前位置: > 華清遠(yuǎn)見教育科技集團(tuán) > 嵌入式學(xué)習(xí) > 講師博文 > Linux下多線程的應(yīng)用
Linux下多線程的應(yīng)用
時(shí)間:2017-01-05作者:華清遠(yuǎn)見

一、創(chuàng)建線程

函數(shù)簡(jiǎn)介

phread_create是UNIX環(huán)境創(chuàng)建線程函數(shù)

頭文件

#include<pthread.h>

函數(shù)聲明

int pthread_create(pthread_t *restrict tidp
                const pthread_attr_t *restrict_addr,
                void *(start_rtn)(void *),
                void *restrict arg);

返回值

若成功則返回0,否則返回出錯(cuò)編號(hào)

返回成功時(shí),由tidp指向的內(nèi)存單元被設(shè)置為新創(chuàng)建線程的線程ID。attr參數(shù)用于制定各種不同的線程屬性。新創(chuàng)建的線程從start_rtn函數(shù)的地址開始運(yùn)行,該函數(shù)只有一個(gè)空指針參數(shù)arg,如果需要像start_rtn函數(shù)傳遞的參數(shù)不止一個(gè),那么需要把這些參數(shù)放到一個(gè)結(jié)構(gòu)體中,然后把這個(gè)結(jié)構(gòu)的地址作為arg的參數(shù)傳入。

linux下用c開發(fā)多線程程序,linux系統(tǒng)下的多線程遵循POSIX線程接口,稱為pthread。

參數(shù)

第一參數(shù)為指向線程標(biāo)識(shí)符的指針
        第二個(gè)參數(shù)用來(lái)設(shè)置線程屬性
        第三個(gè)參數(shù)是線程運(yùn)行函數(shù)的起始地址
        后一個(gè)參數(shù)是運(yùn)行函數(shù)的參數(shù)

另外,在編譯時(shí)注意加上-lpthread參數(shù),以調(diào)用靜態(tài)連接庫(kù)。因?yàn)閜thread并非linux系統(tǒng)的默認(rèn)庫(kù)。

二、pthread_join

函數(shù)pthread_join用來(lái)等待一個(gè)線程的結(jié)束。函數(shù)原型為:

extern int phread_join (pthead_t __th,void **_thread_return);

第一個(gè)參數(shù)為被等待的線程標(biāo)識(shí)符。第二個(gè)參數(shù)為一個(gè)用戶定義的指針,它可以用來(lái)存儲(chǔ)被等待線程的返會(huì)值。這個(gè)函數(shù)是一個(gè)線程阻塞的函數(shù),調(diào)用它的函數(shù)將一直等待到被等待的線程結(jié)束為止,當(dāng)函數(shù)返回時(shí),被等待線程的資源被收回。如果執(zhí)行成功,將返回0,如果失敗則返回一個(gè)錯(cuò)誤號(hào)。

在linux中,默認(rèn)情況下是在一個(gè)線程被創(chuàng)建后,必須使用此函數(shù)對(duì)創(chuàng)建的線程進(jìn)行資源回收,但是可以設(shè)置Threads attributes來(lái)設(shè)置當(dāng)一個(gè)線程結(jié)束時(shí),直接回收此線程所占用的系統(tǒng)資源。

三、 互斥鎖pthread_mutex_t的使用

1.兩種方法創(chuàng)建互斥鎖,靜態(tài)方式和動(dòng)態(tài)方式。

POXIX定義了一個(gè)PTHREAD_MUTEX_INITIALIZER來(lái)靜態(tài)初始化互斥鎖,方法如下:phread_mutex_t mutex=PTHREAD_MUTEX_INITALIZER;在LinuxThreads實(shí)現(xiàn)中,pthread_mutex_t是一個(gè)結(jié)構(gòu),而PTHREAD_MUTEX_INITIALIZER則是一個(gè)結(jié)構(gòu)常量。

動(dòng)態(tài)方式是采用pthread_mutex_init()函數(shù)來(lái)初始化互斥鎖,API定義如下:

int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutexattr_t *mutexattr)其中mutexattr用于指定互斥屬性(見下),如果為NULL則使用缺省屬性。

pthread_mutex_destroy()用于注銷一個(gè)互斥鎖,API定義如下:int pthread_mutex_destory(pthread_mutex_t *mutex) 銷毀一個(gè)互斥鎖即意味著釋放它所占用的資源,且要求鎖當(dāng)前處于開發(fā)狀態(tài)。由于在linux中,互斥鎖并不占用任何資源,因此LinuxThreads中的pthread_mutex_destroy()除了檢查鎖狀態(tài)以外(鎖定狀態(tài)則返回EBUSY)沒有其他動(dòng)作。

2.互斥鎖屬性

互斥鎖的屬性在創(chuàng)建鎖的時(shí)候指定,在LinuxThreads實(shí)現(xiàn)中僅有一個(gè)鎖類型屬性,不通的鎖類型試圖對(duì)一個(gè)已經(jīng)被鎖定的互斥鎖加鎖時(shí)表現(xiàn)不通。當(dāng)前(glibc 2.2.3,linuxthreads0.9)有四個(gè)值可供選擇:

*PTHREAD_MUTEX_TIMED_NP,這是缺省值,也就是普通鎖。當(dāng)一個(gè)線程加鎖以后,其余請(qǐng)求鎖的線程將形成一個(gè)等待隊(duì)列,并在解鎖后按優(yōu)先級(jí)獲得鎖。這種鎖策略保證了資源分配的公平性。

*PTHREAD_MUTEX_RECURSIVE_NP,嵌套鎖,允許同一個(gè)線程對(duì)同一個(gè)鎖成功獲得多次,并通過(guò)多次unlock解鎖。如果是不同線程請(qǐng)求,則在加鎖線程解鎖時(shí)重新競(jìng)爭(zhēng)。

*PTHREAD_MUTEX_ERRORCHECK_NP,檢錯(cuò)鎖,如果同一個(gè)線程請(qǐng)求同一個(gè)鎖,則返回EDEADLK,否則與PTHREAD_MUTEX_TIMED_NP類型動(dòng)作相同。這樣就保證當(dāng)步允許多次加鎖 時(shí)不會(huì)出現(xiàn)簡(jiǎn)單情況下的死鎖。

*PTHREAD_MUTEX_ADAPTIVE_NP,適應(yīng)鎖,動(dòng)作簡(jiǎn)單的鎖類型,僅等待解鎖后重新競(jìng)爭(zhēng)。

3.鎖操作

鎖操作主要包括加鎖pthread_mutex_lock()、解鎖pthread_mutex_unlock()和測(cè)試加鎖pthread_mutex_trylock()三個(gè),不論哪種類型的鎖,都不可能被兩個(gè)不同的線程時(shí)得到,而必須等待解鎖。對(duì)于普通鎖和適應(yīng)鎖類型,解鎖者可以是同進(jìn)程內(nèi)任何線程;而檢錯(cuò)鎖則必須由加鎖者解鎖才有效,否則EPERM;對(duì)于嵌套鎖,文檔和實(shí)現(xiàn)要求必須由加鎖者解鎖,但試驗(yàn)結(jié)果表明并沒有這種限制,這個(gè)不同目前還沒有得到解釋。在同一進(jìn)程中的線程,如果加鎖后沒有解鎖,則任何其他線程都無(wú)法在獲得鎖。

int pthread_mutex_lock(pthread_mutex_t *mutex);
        int pthread_mutex_unlock(pthread_mutex_t *mutex);
        int pthread_mutex_trylock(pthread_mutex_t *mutex);

phread_mutex_trylock()語(yǔ)義與pthread_mutex_lock()類似,不同的是在鎖已經(jīng)被占用時(shí)返回EBUSY而不是掛起等待。

四、使用條件變量提高效率

如果線程正在等待某個(gè)特定條件發(fā)生,它應(yīng)該如何處理這種情況?它可以重復(fù)對(duì)互斥對(duì)象鎖定和解鎖,每次都會(huì)檢查共享數(shù)據(jù)結(jié),以查找某個(gè)值。但這是在浪費(fèi)時(shí)間和資源,而且這種繁忙查詢的效率非常低。解決這個(gè)問題的佳方法是使用pthread_cond_wait()調(diào)用來(lái)等待特殊條件發(fā)生。

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

1.創(chuàng)建和注銷

條件變量和互斥鎖一樣,都有靜態(tài)、動(dòng)態(tài)兩種創(chuàng)建方式,靜態(tài)方式使用PTHREAD_COND_INITIALIZER常量,如下:

pthread_cond_t cond=PTHREAD_COND_INITIALIZER

動(dòng)態(tài)方式調(diào)用pthread_cond_init()函數(shù),API定義如下:

int pthread_cond_init(pthread_cond_t *cond,pthread_condattr_t *cond_attr);

盡管POSIX標(biāo)準(zhǔn)中為條件變量定義了屬性,但在LinuxThreads中沒有實(shí)現(xiàn),因此cond_attr值通常為NULL,且被忽略。

注銷一個(gè)條件變量需要調(diào)用pthread_cond_destroy(),只有在沒有線程在該條件變量上等待的時(shí)候才能注銷這個(gè)條件變量,否則返回EBUSY。因?yàn)長(zhǎng)inux實(shí)現(xiàn)的條件變量沒有分配什么資源,所以注銷動(dòng)作只包括檢查是否有等待線程。API定下如下:

int pthread_cond_destroy(pthread_cond_t *cond);

2.等待和激發(fā)

int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex)
        int pthread_cond_timedwait(pthread_cond_t *cond,pthread_mutex_t *mutex,const struct timespec *abstime)

等待條件有兩種方式:無(wú)條件等待pthread_cond_wait()和計(jì)時(shí)等待pthread_cond_timedwait(),其中計(jì)時(shí)等待如果在給定時(shí)刻前條件沒有滿足,則返回ETIMEOUT,結(jié)束等待,其中abstime以與time()系統(tǒng)調(diào)用相同意義的絕對(duì)時(shí)間形式出現(xiàn),0表示格林時(shí)間1970年1月1日0時(shí)0分0秒。

無(wú)論哪種等待方式,都必須和一個(gè)互斥鎖配合,以防止多個(gè)線程同時(shí)請(qǐng)求pthread_cond_wait()(或pthread_cond_timedwait(),下同)的競(jìng)爭(zhēng)條件。mutex互斥鎖必須是普通鎖(PTHREAD_MUTEX_TIMED_NP)或者適應(yīng)鎖(PTHREAD_MUTEX_ADAPTIVE_NP),且在調(diào)用pthread_cond_wait()前必須給本線程加鎖(pthread_mutex_lock()),而在更新條件等待隊(duì)列以前,mutex保持鎖定狀態(tài),并在線程掛起進(jìn)入等待前解鎖。在條件滿足從而離開pthread_cond_wait()之前,mutex將被重新加鎖,以與進(jìn)入pthread_cond_wait()前的加鎖動(dòng)作對(duì)應(yīng)。

激發(fā)條件有兩種形式,pthread_cond_signal()激活一個(gè)等待該條件的線程,存在多個(gè)等待線程時(shí)按入隊(duì)順序激活其中一個(gè);而pthread_cond_broadcast()則激活所有等待線程。

發(fā)表評(píng)論
評(píng)論列表(網(wǎng)友評(píng)論僅供網(wǎng)友表達(dá)個(gè)人看法,并不表明本站同意其觀點(diǎn)或證實(shí)其描述)