版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
Linux多線程李杰聰世界不是串行的真實(shí)世界中很多事情都是同時(shí)發(fā)生的,而不是按次序發(fā)生。隨著軟硬件的發(fā)展計(jì)算機(jī)也進(jìn)入了并行時(shí)代。程序員也應(yīng)該做好并行程序設(shè)計(jì)的準(zhǔn)備。處理器發(fā)展歷史回顧90年代——增大指令的并行發(fā)射能力,超標(biāo)量處理器。90年代末期至21世紀(jì)初——提高主頻21世紀(jì)——超線程,多核技術(shù)出現(xiàn),主頻不再?zèng)Q定CPU性能。處理器種類通用處理器:intel,amd生產(chǎn)。網(wǎng)絡(luò)處理器:摩托羅拉,powerpc,cavium嵌入式處理器:TI(高通),ARM圖像處理器:nvida銀行卡主卡副卡POSPOS賬戶(¥100)銀行卡POS1POS2if(account>=100){①account=account-100;②return交易成功③}else{return余額不夠④}刷¥100刷¥100正確執(zhí)行(賬戶歸零)Pos1①
Pos1②Pos2①Pos2④Pos1③錯(cuò)誤執(zhí)行(賬戶透支)Pos1①
Pos2①Pos2②Pos2③Pos1②Pos1③時(shí)間并發(fā)的幾個(gè)概念競(jìng)爭(zhēng)(racecondition):程序執(zhí)行的結(jié)果或者輸出取決于某一段代碼的執(zhí)行次序,次序不同結(jié)果不同。競(jìng)爭(zhēng)是不確定的,偶發(fā)性較強(qiáng)。導(dǎo)致系統(tǒng)異常,數(shù)據(jù)被破壞。難以重現(xiàn),調(diào)試,發(fā)現(xiàn)競(jìng)爭(zhēng)。加入調(diào)試代碼時(shí),競(jìng)爭(zhēng)會(huì)消失?!銀行卡存在數(shù)據(jù)競(jìng)爭(zhēng)。并發(fā)的幾個(gè)概念原子性(atomic):是系統(tǒng)中最小的一個(gè)操作集合。銀行卡例子中,更新賬戶余額的操作集合需要時(shí)一個(gè)原子操作。也即
①
②是一個(gè)原子操作,否則引入競(jìng)爭(zhēng)。導(dǎo)致程序運(yùn)行結(jié)果不確定。也可把①
②③④作為原子操作,但會(huì)降低程序性能。對(duì)競(jìng)爭(zhēng)的判斷同時(shí)也是對(duì)原子操作范圍的界定。程序設(shè)計(jì)中,競(jìng)爭(zhēng)區(qū)域判斷比想象中要困難很多。哲學(xué)家問(wèn)題有5個(gè)哲學(xué)家圍坐在一張圓桌上。每相鄰兩個(gè)哲學(xué)家之間有一只筷子。哲學(xué)家除了思考就是吃。當(dāng)哲學(xué)家餓時(shí),他就先拿起作手邊的筷子然后再拿右手邊的筷子。當(dāng)有兩只筷子時(shí),哲學(xué)家開始吃飯,否則一直等待另外一只筷子。哲學(xué)家吃晚飯后,放下筷子,繼續(xù)思考。并發(fā)中的問(wèn)題死鎖(deadlock):兩個(gè)或者以上的線程互相等待,導(dǎo)致整個(gè)系統(tǒng)無(wú)法向前推進(jìn)。例如:5個(gè)哲學(xué)家同時(shí)拿起自己左手邊的筷子,然后等待右手邊的筷子。由于所有筷子均被占有,導(dǎo)致沒(méi)有一個(gè)哲學(xué)家能進(jìn)食。并發(fā)中的問(wèn)題活鎖(livelock):兩個(gè)或者以上的線程會(huì)不斷的執(zhí)行,不斷的改變狀態(tài),但整個(gè)系統(tǒng)卻不朝著最終目的前進(jìn)?;铈i一般為了解決死鎖引入的。死鎖的線程只會(huì)等待,不會(huì)改變狀態(tài)。活鎖會(huì)改變執(zhí)行狀態(tài),但不會(huì)朝著最終目標(biāo)前進(jìn)。為了解決哲學(xué)家的死鎖問(wèn)題。我們規(guī)定:如果哲學(xué)家無(wú)法拿到右手邊的筷子,那么他必須放下他左手邊的筷子。等待一會(huì)兒再去嘗試拿筷子。舉例:5個(gè)哲學(xué)同時(shí)拿起左手邊筷子,發(fā)現(xiàn)右手邊的筷子沒(méi)有,又同時(shí)放下左手上的筷子,如此往復(fù)并發(fā)中的問(wèn)題饑餓、餓死(starvation):某些線程永遠(yuǎn)無(wú)法得到執(zhí)行的機(jī)會(huì)。舉例:某一哲學(xué)家,每次去拿筷子時(shí),左手或者右手邊的筷子被拿走,該哲學(xué)家只能一直“餓肚子”。公平性(fairness):有些線程得到的執(zhí)行機(jī)會(huì)多,有些線程得到的執(zhí)行機(jī)會(huì)少。舉例:哲學(xué)家在拿筷子時(shí),有些哲學(xué)家拿到筷子的可能性可能比其它哲學(xué)家大。比如那些好吃懶做,整天嘗試去拿筷子的哲學(xué)家。多線程概念進(jìn)程是資源分配的對(duì)象,時(shí)間片內(nèi)存等。線程是使用資源的實(shí)體,一個(gè)進(jìn)程中的多個(gè)線程共享內(nèi)存,全局變量,文件描述符等。線程有獨(dú)立的棧和寄存器線程的優(yōu)缺點(diǎn)優(yōu)點(diǎn):上下文切換快共享數(shù)據(jù)容易創(chuàng)建線程速度快缺點(diǎn)內(nèi)存共享會(huì)導(dǎo)致互相干擾一個(gè)線程崩潰會(huì)導(dǎo)致整個(gè)進(jìn)程崩潰用戶級(jí)線程線程可以在用戶層或者內(nèi)核層提供在用戶層實(shí)現(xiàn)線程意味著內(nèi)核并不知道線程的存在。用戶層線程庫(kù)會(huì)實(shí)現(xiàn)線程的創(chuàng)建、刪除、調(diào)度。用戶層的線程創(chuàng)建比較快當(dāng)某個(gè)線程要使用內(nèi)核時(shí),其余線程都會(huì)被掛起。內(nèi)核級(jí)線程內(nèi)核直接支持線程線程的創(chuàng)建、刪除和調(diào)度都有內(nèi)核來(lái)做。一個(gè)線程等待I/O阻塞時(shí),其余線程可以繼續(xù)運(yùn)行。創(chuàng)建等操作要進(jìn)出內(nèi)核,速度會(huì)慢些。目前流行的操作系統(tǒng)都支持內(nèi)核級(jí)線程。多線程模型內(nèi)核線程和用戶線程的對(duì)應(yīng)關(guān)系一個(gè)內(nèi)核線程對(duì)應(yīng)n個(gè)用戶線程(用戶級(jí)線程)一個(gè)內(nèi)核線程對(duì)應(yīng)一個(gè)用戶線程(內(nèi)核級(jí)線程)用戶級(jí)線程內(nèi)核級(jí)線程多線程中的fork在linux系統(tǒng)當(dāng)一個(gè)擁有多線程的進(jìn)程調(diào)用fork時(shí),子進(jìn)程只會(huì)有一個(gè)線程!fork()多線程中的信號(hào)在linux系統(tǒng)中信號(hào)是用來(lái)通知進(jìn)程特殊事件發(fā)生了多線程中有哪個(gè)線程來(lái)處理呢?信號(hào)會(huì)被遞送給恰當(dāng)?shù)木€程,比如SIGILL非法指令。信號(hào)會(huì)被遞送給進(jìn)程中任意的線程處理。在多線程環(huán)境我們一般指定一個(gè)線程專門處理信號(hào),其余線程全部屏蔽信號(hào)處理。線程池在程序設(shè)計(jì)中,并不是來(lái)一個(gè)任務(wù)/請(qǐng)求就創(chuàng)建一個(gè)線程,執(zhí)行完畢線程退出。程序初始化時(shí)創(chuàng)建一個(gè)線程池,線程池中有n個(gè)線程。當(dāng)一個(gè)請(qǐng)求來(lái)時(shí),從線程池中取一個(gè)線程,完成請(qǐng)求后線程再放回線程池。節(jié)省了頻繁創(chuàng)建線程和銷毀線程的開銷。pthreadAPOSIXstandard(IEEE1003.1c)APIforthreadcreationandsynchronization。pthread大概有60多個(gè)函數(shù),包括線程的創(chuàng)建、終止等。Linux中實(shí)現(xiàn)了pthread線程庫(kù)Unix/Widows中也有pthread的實(shí)現(xiàn)。Linux中使用pthead方法為:#include<pthread.h>gccmain.c–lpthread注意:必須加lpthread,不像glibc庫(kù),gcc不會(huì)自動(dòng)去鏈接pthread庫(kù)。線程創(chuàng)建:pthread_create()pthread_create用來(lái)創(chuàng)建一個(gè)線程。成功返回0,失敗返回非0。thread指向內(nèi)存單元將被設(shè)置為新創(chuàng)建的線程ID,attr是要?jiǎng)?chuàng)建線程的屬性(NULL為默認(rèn)屬性),start_routine為線程開始執(zhí)行的函數(shù),arg為start_routine的參數(shù)。線程共享全局變量,在一個(gè)線程中改變對(duì)另外線程可見(jiàn)。#include<pthread.h>intpthread_create(pthread_t*restrictthread,constpthread_attr_t*restrictattr,void*(*start_routine)(void*),void*restrictarg);pthread_create()arg不能是局部變量,否則線程使用該變量時(shí)可能已經(jīng)被修改或者不存在了。start_routine的參數(shù)和返回值都為void*,如果有多個(gè)參數(shù),那只能打包成一個(gè)結(jié)構(gòu)體了。返回值不能是局部變量?。≈骶€程退出,則整個(gè)進(jìn)程結(jié)束。線程終止如果進(jìn)程中的任意線程調(diào)用exit、_exit、_Exit,那么整個(gè)進(jìn)程都會(huì)被終止。線程從啟動(dòng)函數(shù)中返回,返回值是線程的退出碼。線程可以被其他線程取消線程調(diào)用pthread_exit退出。pthread_exit調(diào)用pthread_exit后,線程終止。參數(shù)value_ptr會(huì)被后來(lái)調(diào)用pthread_join函數(shù)的線程獲得!pthread_join的第一個(gè)參數(shù)指定某個(gè)線程,第二個(gè)參數(shù)用來(lái)接收線程的退出值。#include<pthread.h>voidpthread_exit(void*value_ptr);intpthread_join(pthread_tthread,void**value_ptr);線程IDpthread_self返回調(diào)用線程的線程ID。當(dāng)比較兩個(gè)線程是否是同一個(gè)線程,需要用pthread_equal.#include<pthread.h>pthread_tpthread_self(void);intpthread_equal(pthread_tt1,pthread_tt2);線程屬性pthread_create的第二個(gè)參數(shù)就是線程的屬性,傳入NULL表示使用默認(rèn)屬性??梢杂眠^(guò)pthreadAPI來(lái)修改線程的屬性。線程分離屬性當(dāng)一個(gè)線程被創(chuàng)建時(shí),系統(tǒng)給它創(chuàng)建一個(gè)線程控制塊(由threadid來(lái)標(biāo)識(shí))。如果線程沒(méi)有設(shè)置分離屬性,那么需要其它線程通過(guò)pthread_join來(lái)回收這個(gè)線程控制塊。如果設(shè)置了分離屬性,那么線程結(jié)束時(shí)自動(dòng)釋放創(chuàng)建時(shí)分配的資源。pthread_detach用來(lái)設(shè)置分離屬性,但須注意必須在新創(chuàng)建的線程結(jié)束之前!一般來(lái)說(shuō)這個(gè)函數(shù)是有新建線程進(jìn)入啟動(dòng)函數(shù)后立馬調(diào)用的,pthread_detach(pthread_self())#include<pthread.h>intpthread_detach(pthread_tthread);線程屬性pthread_attr_init用默認(rèn)值初始化線程的屬性。成功返回0,失敗返回非0值。pthread_attr_destroy用來(lái)銷毀init分配的內(nèi)存。該函數(shù)理論上都會(huì)執(zhí)行成功,除非你傳入了一個(gè)非法的屬性指針。成功返回0,失敗返回非0。#include<pthread.h>intpthread_attr_destroy(pthread_attr_t*attr);intpthread_attr_init(pthread_attr_t*attr);線程分離屬性兩個(gè)函數(shù)的第一個(gè)參數(shù)都是屬性。pthread_attr_setdetachstate用來(lái)設(shè)置分離屬性,第二個(gè)參數(shù)有兩個(gè)值PTHREAD_CREATE_DETACHED和PTHREAD_CREATE_JOINABLE。pthread_attr_getdetachstate用來(lái)獲取分離狀態(tài)。注意:線程一旦設(shè)置了分離狀態(tài),再調(diào)用pthread_join就會(huì)出錯(cuò)。#include<pthread.h>intpthread_attr_getdetachstate(constpthread_attr_t*attr,int*detachstate);intpthread_attr_setdetachstate(pthread_attr_t*attr,intdetachstate);線程棧屬性進(jìn)程棧空間需要被不同的線程共享,所以可能會(huì)出現(xiàn)棧空間不夠的情況。此時(shí)可以用malloc從堆中分配內(nèi)存給線程當(dāng)做棧來(lái)使用。pthread_attr_setstack設(shè)置堆棧時(shí),第二個(gè)參數(shù)是內(nèi)存的起始地址,第三個(gè)參數(shù)為內(nèi)存的大小。pthread_attr_setstacksize可以在不處理?xiàng)7峙涞那闆r下,改變線程堆棧的大小。#include<pthread.h>intpthread_attr_getstack(constpthread_attr_t*restrictattr,void**restrictstackaddr,size_t*restrictstacksize);intpthread_attr_setstack(pthread_attr_t*attr,void*stackaddr,size_tstacksize);intpthread_attr_setstacksize(pthread_attr_t*attr,size_tstacksize);線程棧屬性guardsize用來(lái)設(shè)置棧溢出后,還可以使用的棧的大小,一般為一個(gè)PAGESIZE。也稱警戒緩沖區(qū)。如果我們對(duì)stackaddr做了修改,那么系統(tǒng)會(huì)假設(shè)我們自己會(huì)管理?xiàng)#粫?huì)提供警戒緩沖區(qū)給我們使用。相當(dāng)于設(shè)置guardsize為0。#include<pthread.h>intpthread_attr_getguardsize(constpthread_attr_t*restrictattr,size_t*restrictguardsize);intpthread_attr_setguardsize(pthread_attr_t*attr,size_tguardsize);線程同步當(dāng)多個(gè)線程共享相同的內(nèi)存時(shí),就需要確保每個(gè)線程看到一致的數(shù)據(jù)。如果數(shù)據(jù)是只讀的,那么不存在一致性問(wèn)題。如果線程對(duì)數(shù)據(jù)有讀有寫,這時(shí)候就需要同步機(jī)制來(lái)保證數(shù)據(jù)的一致性。線程同步需要一種機(jī)制確保變量修改時(shí),只有一個(gè)線程在訪問(wèn)。這樣就能保證數(shù)據(jù)的一致性?;コ饬课覀兛梢允褂胮thread庫(kù)提供的互斥量來(lái)確保同一時(shí)間只有一個(gè)線程訪問(wèn)數(shù)據(jù)?;コ饬科鋵?shí)就是一種鎖,在訪問(wèn)共享數(shù)據(jù)之前設(shè)置這個(gè)鎖,訪問(wèn)完之后釋放這個(gè)鎖?;コ饬恳坏┍患恿随i,其他任何線程再也不能在這個(gè)互斥量上加鎖,需等到鎖被釋放。互斥量互斥量的類型為pthread_mutex_t,要?jiǎng)?chuàng)建一個(gè)互斥量要么使用靜態(tài)方式創(chuàng)建(用PTHREAD_MUTEX_INITIALIZER來(lái)初始化),要么調(diào)用函數(shù)創(chuàng)建。pthread_mutex_init函數(shù)的第一個(gè)參數(shù)接受該函數(shù)創(chuàng)建的互斥量。第二個(gè)參數(shù)為互斥量屬性,可以為NULL。#include<pthread.h>intpthread_mutex_init(pthread_mutex_t*mutex,constpthread_mutexattr_t*attr);intpthread_mutex_destroy(pthread_mutex_t*mutex);互斥量pthread_mutex_destroy用來(lái)銷毀由init函數(shù)創(chuàng)建的互斥量,如果是靜態(tài)創(chuàng)建的則無(wú)需調(diào)用destroy函數(shù)。兩個(gè)函數(shù)都是成功返回0,失敗返回非0值?;コ饬考渔iintpthread_mutex_lock(pthread_mutex_t*mutex);給互斥量mutex加鎖。如果此互斥量已經(jīng)加鎖,那么調(diào)用該函數(shù)的線程會(huì)被阻塞,如果互斥量沒(méi)加鎖,調(diào)用線程給該互斥量加鎖。參數(shù)mutex是由init函數(shù)創(chuàng)建或者靜態(tài)初始化。成功返回0,失敗返回非0.互斥量加鎖intpthread_mutex_trylock(pthread_mutex_t*mutex);只是嘗試加鎖,看鎖是否能加上。如果鎖能加上則返回0,不能加上errno設(shè)置成EBUSY,錯(cuò)誤返回其余值。參數(shù)mutex跟lock函數(shù)一樣。線程可以用trylock去檢查某個(gè)mutex是否加鎖。如果加鎖了,它就先去執(zhí)行其它任務(wù),以此增加并發(fā)性!互斥量解鎖intpthread_mutex_unlock(pthread_mutex_t*mutex);釋放互斥量成功返回0,失敗返回非0死鎖問(wèn)題如果線程已經(jīng)對(duì)互斥量加鎖了,再對(duì)這個(gè)互斥量調(diào)用pthread_mutex_lock,那么此時(shí)該線程被死鎖。假設(shè)有A、B兩個(gè)互斥量,線程A先對(duì)A互斥量加鎖,然后線程B對(duì)B互斥量加鎖,然后線程A又去對(duì)B互斥量加鎖,而線程B又去對(duì)A互斥量加鎖。此時(shí)兩個(gè)線程產(chǎn)生死鎖。有多個(gè)互斥量時(shí),要注意加鎖的次序以避免死鎖。讀寫鎖讀寫鎖提供了比互斥量更好的并發(fā)性?;コ饬恐挥屑渔i和不加鎖兩個(gè)狀態(tài),同一時(shí)間只允許一個(gè)線程加鎖。讀寫鎖有三個(gè)狀態(tài):讀鎖、寫鎖、不加鎖。同一時(shí)刻只有一個(gè)線程能擁有寫鎖,但是同一時(shí)刻可以有多個(gè)線程可以擁有讀鎖。加了寫鎖后,任何線程都不能再加鎖。加了讀鎖后,任何線程都可以對(duì)它加讀鎖,只有一個(gè)能加寫鎖。讀寫鎖適合讀比較頻繁,寫比較少的情況,比如數(shù)據(jù)庫(kù)。讀寫鎖intpthread_rwlock_init(pthread_rwlock_t*restrictrwlock,const pthread_rwlockattr_t*restrictattr);intpthread_rwlock_destroy(pthread_rwlock_t*rwlock);第一個(gè)參數(shù)返回讀寫鎖對(duì)象,第二個(gè)參數(shù)使用NULL表示默認(rèn)屬性。返回0表示成功,失敗返回非0。當(dāng)要釋放讀寫鎖時(shí),必須先調(diào)用destroy函數(shù)!PTHREAD_RWLOCK_INITIALIZER可以初始化靜態(tài)分配的讀寫鎖。讀寫鎖intpthread_rwlock_rdlock(pthread_rwlock_t*rwlock);intpthread_rwlock_wrlock(pthread_rwlock_t*rwlock);intpthread_rwlock_unlock(pthread_rwlock_t*rwlock);加讀鎖時(shí)要注意判斷返回值,因?yàn)榧幼x鎖的次數(shù)可能有限制!所以加讀鎖是會(huì)失敗的。加寫鎖無(wú)須判斷返回值,寫鎖只能加一次。無(wú)論加的是寫鎖還是讀鎖,都用pthread_rwlock_unlock解鎖。成功返回0,不成功返回非0讀寫鎖intpthread_rwlock_tryrdlock(pthread_rwlock_t*rwlock);intpthread_rwlock_trywrlock(pthread_rwlock_t*rwlock);檢查是否能加鎖,能加鎖返回0,不能加鎖返回EBUSY,失敗返回其余值。tryrdlock和trywrlock可以提高并發(fā)性。條件變量條件變量是另一種同步機(jī)制。多個(gè)線程可以等待同一個(gè)條件,條件滿足時(shí)被喚醒??梢詥拘岩粋€(gè)線程,也可以喚醒所有等待的線程。條件變量跟互斥量mutex一起使用。條件變量的類型是pthread_cond_t條件變量intpthread_cond_init(pthread_cond_t*restrictcond,pthread_condattr_t*restrictattr);intpthread_cond_destroy(pthread_cond_t*cond);條件變量可以用PTHREAD_COND_INITIALIZER靜態(tài)初始化。函數(shù)pthread_cond_init動(dòng)態(tài)的初始化條件變量,第二個(gè)參數(shù)為NULL,使用默認(rèn)屬性。條件變量需要destroy函數(shù)釋放。成功返回0,失敗返回其余值。條件變量intpthread_cond_wait(pthread_cond_t*restrictcond,pthread_mutex_t*restrictmutex);intpthread_cond_timedwait(pthread_cond_t*restrictcond,pthread_mutex_t*restrictmutex,conststructtimespec*restricttimeout);pthread_cond_wait第一個(gè)參數(shù)為初始化后的條件變量,第二個(gè)參數(shù)為初始化后的互斥量。首先會(huì)被調(diào)用線程放入等待條件變量的隊(duì)列,然后釋放mutex,直到條件滿足時(shí)被喚醒,喚醒從函數(shù)返回時(shí)再對(duì)mutx加鎖。pthread_cond_timewait比第一個(gè)函數(shù)多一個(gè)參數(shù),這個(gè)參數(shù)指定了等待時(shí)間。如果時(shí)間到了還沒(méi)被喚醒,那么返回ETIMEDOUT條件變量intpthread_cond_signal(pthread_cond_t*cond);intpthread_cond_broadcast(pthread_cond_t*cond);喚醒等待在條件變量上的線程,如果沒(méi)有線程等待在條件變量上,這個(gè)喚醒動(dòng)作是不會(huì)被保留的!函數(shù)pthread_cond_signal只會(huì)喚醒其中一個(gè)線程,pthread_cond_broadcast喚醒所有線程。條件變量使用多個(gè)線程等待一個(gè)計(jì)數(shù)器達(dá)到一個(gè)值時(shí)被喚醒。ThreadA
pthread_mutex_lock(&lock);count++;if(count>=MAX_COUNT){pthread_cond_signal(&cond);}pthread_mutex_unlock(&lock)ThreadBpthread_mutex_lock(&lock);while(count<MAX_COUNT){
pthread_cond_wait(&cond,&lock);}count--;pthread_mutex_unlock(&lock)多個(gè)線程等待一個(gè)計(jì)數(shù)器達(dá)到一個(gè)值時(shí)被喚醒。ThreadApthread_mutex_lock(&lock);count++;if(count>=MAX_COUNT){pthread_cond_signal(&cond);}pthread_mutex_unlock(&lock)ThreadBpthread_mutex_lock(&lock);while(count<MAX_COUNT){pthread_mutex_unlock(&lock)
pthread_cond_wait(&cond);pthread_mutex_lock(&lock);}count--;pthread_mutex_unlock(&lock)條件變量使用ThreadA當(dāng)滿足條件時(shí)候發(fā)一個(gè)信號(hào)。ThreadB先給一個(gè)mutex加鎖,以便互斥訪問(wèn)count的值。在一個(gè)while循環(huán)里等待count值達(dá)到MAX_COUNT。因?yàn)楫?dāng)某個(gè)條件滿足時(shí),可能會(huì)有多個(gè)線程被喚醒你,所以需要判斷條件是否還滿足。pthread_cond_wait首先把調(diào)用線程放入條件變量的等待隊(duì)列,然后再釋放mutex。當(dāng)函數(shù)返回時(shí),mutex又會(huì)被加上鎖。最后會(huì)對(duì)mutex解鎖,讓其他線程使用count變量?;コ饬繉傩詐thread_mutexattr_init用默認(rèn)的屬性互斥量屬性初始化attrinit函數(shù)初始化的互斥量屬性必須由pthread_mutexattr_destroy來(lái)釋放?;コ饬坑羞M(jìn)程共享屬性和類型屬性。#include<pthread.h>intpthread_mutexattr_init(pthread_mutexattr_t*attr);intpthread_mutexattr_destroy(pthread_mutexattr_t*attr);互斥量屬性互斥量進(jìn)程共享屬性當(dāng)互斥量只在同一進(jìn)程的不同線程使用時(shí),pshared應(yīng)該設(shè)置為PTHREAD_PROCESS_PRIVATE當(dāng)互斥量在不同進(jìn)程間以共享內(nèi)存方式使用時(shí),pshared應(yīng)該設(shè)置為PTHREAD_PROCESS_SHARED#include<pthread.h>intpthread_mutexattr_getpshared(constpthread_mutexattr_t*restrictattr,int*restrictpshared);intpthread_mutexattr_setpshared(pthread_mutexattr_t*attr,intpshared);互斥量類型屬性#include<pthread.h>intpthread_mutexattr_gettype(constpthread_mutexattr_t*restrictattr,int*restricttype);intpthread_mutexattr_settype(pthread_mutexattr_t*attr,inttype);讀寫鎖屬性讀寫鎖和條件變量只提供了進(jìn)程共享屬性#include<pthread.h>intpthread_rwlockattr_init(pthread_rwlockattr_t*attr);intpthread_rwlockattr_destroy(pthread_rwlockattr_t*attr);intpthread_rwlockattr_getpshared(constpthread_rwlockattr_t*restrictattr,int*restrictpshared);intpthread_rwlockattr_setpshared(pthread_rwlockattr_t*attr,intpshared);#include<pthread.h>intpthread_condattr_init(pthread_condattr_t*attr);intpthread_condattr_destroy(pthread_condattr_t*attr);intpthread_condattr_getpshared(constpthread_condattr_t*restrictattr,int*restrictpshared);intpthread_condattr_setpshared(pthread_condattr_t*attr,intpshared);運(yùn)行一次線程有時(shí)候在多線程環(huán)境中只想讓某個(gè)函數(shù)執(zhí)行一次。pthread_once保證了initfn只會(huì)運(yùn)行一次。initflag必須是全局或者靜態(tài)的,不能是局部變量。而且必須初始化為PTHREAD_ONCE_INIT#include<pthread.h>pthread_once_tinitflag=PTHREAD_ONCE_INIT;intpthread_once(pthread_once_t*initflag,void(*initfn)(void));信號(hào)量#include<semaphore.h>intsem_init(sem_t*sem,intpshared,uns
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 安徽體育行業(yè)教練勞動(dòng)合同樣本3篇
- 教育培訓(xùn)崗位勞動(dòng)合同樣本3篇
- 數(shù)據(jù)處理與分析合同3篇
- 教育培訓(xùn)合作協(xié)議攜手培養(yǎng)人才3篇
- 撤銷刑事委托代理合同3篇
- 房屋買賣合同的案例分析3篇
- 教育機(jī)構(gòu)清潔維護(hù)租賃合同3篇
- 招標(biāo)文件簡(jiǎn)易編寫要點(diǎn)3篇
- 圖書館標(biāo)線施工協(xié)議
- 租賃合同范本:包裝工具
- 2024年“七五”普法考試題庫(kù)及答案(共100題)
- 風(fēng)電、光伏技術(shù)標(biāo)準(zhǔn)清單
- 備用電源使用安全管理制度
- DB34∕T 4504-2023 中醫(yī)治未病科設(shè)施配置指南
- 小學(xué)2024-2026年學(xué)校三年發(fā)展規(guī)劃
- 武漢理工大學(xué)JAVA語(yǔ)言程序設(shè)計(jì)期末復(fù)習(xí)題
- HG∕T 3684-2017 搪玻璃雙錐形回轉(zhuǎn)式真空干燥機(jī)
- 企業(yè)數(shù)字化轉(zhuǎn)型對(duì)組織韌性的影響研究
- GB/T 24977-2024衛(wèi)浴家具通用技術(shù)條件
- 2024-2030年中國(guó)船舶用傳動(dòng)軸行業(yè)市場(chǎng)研究及發(fā)展前景預(yù)測(cè)報(bào)告
- CJT272-2008 給水用抗沖改性聚氯乙烯(PVCM)管材及管件
評(píng)論
0/150
提交評(píng)論