當(dāng)前位置:首頁(yè) > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 學(xué)習(xí)筆記 > Linux線程屬性有哪些?看了這個(gè)就知道
線程屬性標(biāo)識(shí)符:pthread_attr_t 包含在 pthread.h 頭文件中。
[c]view plaincopy
1. //線程屬性結(jié)構(gòu)如下:
2. typedefstruct
3. {
4.intetachstate;//線程的分離狀態(tài)
5.intschedpolicy;//線程調(diào)度策略
6.structsched_paramschedparam;//線程的調(diào)度參數(shù)
7.intinheritsched;//線程的繼承性
8.intscope;//線程的作用域
9.size_tguardsize;//線程棧末尾的警戒緩沖區(qū)大小
10.intstackaddr_set; //線程的棧設(shè)置
11. void*stackaddr;//線程棧的位置
12.size_tstacksize;//線程棧的大小
13.}pthread_attr_t;
屬性值不能直接設(shè)置,須使用相關(guān)函數(shù)進(jìn)行操作,初始化的函數(shù)為
pthread_attr_init,這個(gè)函數(shù)必須在pthread_create函數(shù)之前調(diào)用。之后須用pthread_attr_destroy函數(shù)來(lái)釋放資源。線程屬性主要包括如下屬性:作用域(scope)、棧尺寸(stack size)、棧地址(stack address)、優(yōu)先級(jí)
(priority)、分離的狀態(tài)(detached state)、調(diào)度策略和參數(shù)(scheduling policy and parameters)。默認(rèn)的屬性為非綁定、非分離、缺省1M的堆棧、與父進(jìn)程同樣級(jí)別的優(yōu)先級(jí)。
一、線程的作用域(scope)
作用域?qū)傩悦枋鎏囟ň程將與哪些線程競(jìng)爭(zhēng)資源。線程可以在兩種競(jìng)爭(zhēng)域內(nèi)競(jìng)爭(zhēng)資源:
1. 進(jìn)程域(process scope):與同一進(jìn)程內(nèi)的其他線程。
2. 系統(tǒng)域(system scope):與系統(tǒng)中的所有線程。一個(gè)具有系統(tǒng)域的線程將與整個(gè)系統(tǒng)中所有具有系統(tǒng)域的線程按照優(yōu)先級(jí)競(jìng)爭(zhēng)處理器資源,進(jìn)行調(diào)度。
3. Solaris系統(tǒng),實(shí)際上,從 Solaris 9 發(fā)行版開(kāi)始,系統(tǒng)就不再區(qū)分這兩個(gè)范圍。
二、線程的綁定狀態(tài)(binding state)
輕進(jìn)程(LWP:Light Weight Process)關(guān)于線程的綁定,牽涉到另外一個(gè)概念:輕進(jìn)程(LWP:Light Weight Process):輕進(jìn)程可以理解為內(nèi)核線程,它位于用戶層和系統(tǒng)層之間。系統(tǒng)對(duì)線程資源的分配、對(duì)線程的控制是通過(guò)輕進(jìn)程來(lái)實(shí)現(xiàn)的,一個(gè)輕進(jìn)程可以控制一個(gè)或多個(gè)線程。
1. 非綁定狀態(tài)
默認(rèn)狀況下,啟動(dòng)多少輕進(jìn)程、哪些輕進(jìn)程來(lái)控制哪些線程是由系統(tǒng)來(lái)控制的,這種狀況即稱為非綁定的。
2. 綁定狀態(tài)
綁定狀況下,則顧名思義,即某個(gè)線程固定的"綁"在一個(gè)輕進(jìn)程之上。被綁定的線程具有較高的響應(yīng)速度,這是因?yàn)镃PU時(shí)間片的調(diào)度是面向輕進(jìn)程的,綁定的線程可以保證在需要的時(shí)候它總有一個(gè)輕進(jìn)程可用。通過(guò)設(shè)置被綁定的輕進(jìn)程的優(yōu)先級(jí)和調(diào)度級(jí)可以使得綁定的線程滿足諸如實(shí)時(shí)反應(yīng)之類的要求。
三、線程的分離狀態(tài)(detached state)
1. 線程的分離狀態(tài)決定一個(gè)線程以什么樣的方式來(lái)終止自己。
2. 非分離狀態(tài)
線程的默認(rèn)屬性是非分離狀態(tài),這種情況下,原有的線程等待創(chuàng)建的線程結(jié)束。只有當(dāng)pthread_join()函數(shù)返回時(shí),創(chuàng)建的線程才算終止,才能釋放自己占用的系統(tǒng)資源。
3. 分離狀態(tài)
分離線程沒(méi)有被其他的線程所等待,自己運(yùn)行結(jié)束了,線程也就終止了,馬上釋放系統(tǒng)資源。應(yīng)該根據(jù)自己的需要,選擇適當(dāng)?shù)姆蛛x狀態(tài)。
4. 線程分離狀態(tài)的函數(shù):pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)。
第二個(gè)參數(shù)可選為PTHREAD_CREATE_DETACHED(分離線程)和 PTHREAD _CREATE_JOINABLE(非分離線程)。
這里要注意的一點(diǎn)是,如果設(shè)置一個(gè)線程為分離線程,而這個(gè)線程運(yùn)行又非?,它很可能在pthread_create函數(shù)返回之前就終止了,它終止以后就可能將線程號(hào)和系統(tǒng)資源移交給其他的線程使用,這樣調(diào)用pthread_create的線程就得到了錯(cuò)誤的線程號(hào)。要避免這種情況可以采取一定的同步措施,最簡(jiǎn)單的方法之一是可以在被創(chuàng)建的線程里調(diào)用pthread_cond_timewait函數(shù),讓這個(gè)線程等待一會(huì)兒,留出足夠的時(shí)間讓函數(shù)pthread_create返回。設(shè)置一段等待時(shí)間,是在多線程編程里常用的方法。但是注意不要使用諸如wait()之類的函數(shù),它們是使整個(gè)進(jìn)程睡眠,并不能解決線程同步的問(wèn)題。
四、線程的優(yōu)先級(jí)(priority)
1. 新線程的優(yōu)先級(jí)為默認(rèn)為0。
2. 新線程不繼承父線程調(diào)度優(yōu)先級(jí)(PTHREAD_EXPLICIT_SCHED)
3. 僅當(dāng)調(diào)度策略為實(shí)時(shí)(即SCHED_RR或SCHED_FIFO)時(shí)才有效,并可以在運(yùn)行時(shí)通過(guò)pthread_setschedparam()函數(shù)來(lái)改變,缺省為0。
五、線程的棧地址(stack address)
1. POSIX.1定義了兩個(gè)常量_POSIX_THREAD_ATTR_STACKADDR 和_POSIX_THREAD_ATTR_STACKSIZE檢測(cè)系統(tǒng)是否支持棧屬性。
2. 也可以給sysconf函數(shù)傳遞_SC_THREAD_ATTR_STACKADDR或
_SC_THREAD_ATTR_STACKSIZE來(lái)進(jìn)行檢測(cè)。
3. 當(dāng)進(jìn)程棧地址空間不夠用時(shí),指定新建線程使用由malloc分配的空間作為自己的棧空間。通過(guò)pthread_attr_setstackaddr和pthread_attr_getstackaddr兩個(gè)函數(shù)分別設(shè)置和獲取線程的棧地址。傳給pthread_attr_setstackaddr函數(shù)的地址是緩沖區(qū)的低地址(不一定是棧的開(kāi)始地址,棧可能從高地址往低地址增長(zhǎng))。
六、線程的棧大小(stack size)
1. 當(dāng)系統(tǒng)中有很多線程時(shí),可能需要減小每個(gè)線程棧的默認(rèn)大小,防止進(jìn)程的地址空間不夠用
2. 當(dāng)線程調(diào)用的函數(shù)會(huì)分配很大的局部變量或者函數(shù)調(diào)用層次很深時(shí),可能需要增大線程棧的默認(rèn)大小。
3. 函數(shù)pthread_attr_getstacksize和 pthread_attr_setstacksize提供設(shè)置。
七、線程的棧保護(hù)區(qū)大小(stack guard size)
1. 在線程棧頂留出一段空間,防止棧溢出。
2. 當(dāng)棧指針進(jìn)入這段保護(hù)區(qū)時(shí),系統(tǒng)會(huì)發(fā)出錯(cuò)誤,通常是發(fā)送信號(hào)給線程。
3. 該屬性默認(rèn)值是PAGESIZE大小,該屬性被設(shè)置時(shí),系統(tǒng)會(huì)自動(dòng)將該屬性大小補(bǔ)齊為頁(yè)大小的整數(shù)倍。
4. 當(dāng)改變棧地址屬性時(shí),棧保護(hù)區(qū)大小通常清零。
八、線程的調(diào)度策略(schedpolicy)
POSIX標(biāo)準(zhǔn)指定了三種調(diào)度策略:先入先出策略 (SCHED_FIFO)、循環(huán)策略 (SCHED_RR) 和自定義策略 (SCHED_OTHER)。SCHED_FIFO 是基于隊(duì)列的調(diào)度程序,對(duì)于每個(gè)優(yōu)先級(jí)都會(huì)使用不同的隊(duì)列。SCHED_RR 與 FIFO 相似,不同的是前者的每個(gè)線程都有一個(gè)執(zhí)行時(shí)間配額。SCHED_FIFO 和 SCHED_RR 是對(duì) POSIX Realtime 的擴(kuò)展。SCHED_OTHER 是缺省的調(diào)度策略。
1. 新線程默認(rèn)使用 SCHED_OTHER 調(diào)度策略。線程一旦開(kāi)始運(yùn)行,直到被搶占或者直到線程阻塞或停止為止。
2. SCHED_FIFO
如果調(diào)用進(jìn)程具有有效的用戶 ID 0,則爭(zhēng)用范圍為系統(tǒng)
(PTHREAD_SCOPE_SYSTEM) 的先入先出線程屬于實(shí)時(shí) (RT) 調(diào)度類。如果這些線程未被優(yōu)先級(jí)更高的線程搶占,則會(huì)繼續(xù)處理該線程,直到該線程放棄或阻塞為止。對(duì)于具有進(jìn)程爭(zhēng)用范圍 (PTHREAD_SCOPE_PROCESS)) 的線程或其調(diào)用進(jìn)程沒(méi)有有效用戶 ID 0 的線程,請(qǐng)使用 SCHED_FIFO,SCHED_FIFO 基于 TS 調(diào)度類。
3. SCHED_RR
如果調(diào)用進(jìn)程具有有效的用戶 ID 0,則爭(zhēng)用范圍為系統(tǒng)
(PTHREAD_SCOPE_SYSTEM)) 的循環(huán)線程屬于實(shí)時(shí) (RT) 調(diào)度類。如果這些線程未被優(yōu)先級(jí)更高的線程搶占,并且這些線程沒(méi)有放棄或阻塞,則在系統(tǒng)確定的時(shí)間段內(nèi)將一直執(zhí)行這些線程。對(duì)于具有進(jìn)程爭(zhēng)用范圍 (PTHREAD_SCOPE_PROCESS)
的線程,請(qǐng)使用 SCHED_RR(基于 TS 調(diào)度類)。此外,這些線程的調(diào)用進(jìn)程沒(méi)有有效的用戶 ID 0。
九、線程并行級(jí)別(concurrency)
應(yīng)用程序使用 pthread_setconcurrency() 通知系統(tǒng)其所需的并發(fā)級(jí)別。