POSIX 線程庫定義了線程屬性對象 pthread_attr_t ,它封裝了線程的創建者能夠訪問和改動的線程屬性。主要包含例如以下屬性:
1. 作用域(scope)
2. 棧尺寸(stack size)
3. 棧地址(stack address)
4. 優先級(priority)
5. 分離的狀態(detached state)
6. 調度策略和參數(scheduling policy and parameters)
線程屬性對象能夠與一個線程或多個線程相關聯。當使用線程屬性對象時。它是對線程和線程組行為的配置。使用屬性對象的全部線程都將具有由屬性對象所定義的全部屬 性。盡管它們共享屬性對象。但它們維護各自獨立的線程 ID 和寄存器。
初始化/銷毀線程屬性
int pthread_attr_init(pthread_attr_t *attr); int pthread_attr_destroy(pthread_attr_t *attr);線程分離屬性
int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate); int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);線程棧大小
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize); int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *stacksize);
普通情況下該值我們設置為0,使用系統默認設置的線程棧大小。否則可能會引起程序的可移植性的問題
int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize); int pthread_attr_getguardsize(pthread_attr_t *attr, size_t *guardsize);
guardsize意思是假設我們使用線程棧超過了設定大小之后,系統還會使用部分擴展內存來防止棧溢出。而這部分擴展內存大小就是guardsize. 只是假設自己改動了棧分配位置的話,那么這個選項失效,效果相當於將guardsize設置為0.
每一個線程都存在自己的堆棧。假設這些堆棧是相連的話,訪問超過自己的堆棧的話那么可能會改動到其它線程的堆棧。 假設我們設置了guardsize的話,線程堆棧會多開辟guarszie大小的內存,當訪問到這塊內存時會觸發SIGSEGV信號。
線程競爭范圍(進程范圍內的競爭 or 系統范圍內的競爭)int pthread_attr_getscope(const pthread_attr_t *attr,int *contentionscope); int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope);
線程能夠在兩種競爭域內競爭資源:
1. 進程域(process scope):與同一進程內的其它線程
2. 系統域(system scope):與系統中的全部線程
作用域屬性描寫敘述特定線程將與哪些線程競爭資源。一個具有系統域的線程將與整個系 統中全部具有系統域的線程依照優先級競爭處理器資源,進行調度。
int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy); int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
進程的調度策略和優先級屬於主線程,換句話說就是設置進程的調度策略和優先級僅僅 會影響主線程的調度策略和優先級。而不會改變對等線程的調度策略和優先級(注這句話不全然正確)。
每一個對等線程能夠擁有它自己的獨立於主線程的調度策略和優先級。
在 Linux 系統中,進程有三種調度策略:SCHED_FIFO(先進先出調度策略)、SCHED_RR(時間片輪轉調度算法) 和 SCHED_OTHER(線程一旦開始執行,直到被搶占或者直到線程堵塞或停止為止)。線程也不例外。也具有這三種策略。
線程繼承的調度策略int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched); int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched);
在 pthread 庫中,提供了一個函數,用來設置被創建的線程的調度屬性:是從創建者線 程繼承調度屬性(調度策略和優先級),還是從屬性對象設置調度屬性。該函數就是:
int pthread_attr_setinheritsched (pthread_attr_t * attr, int inherit) 當中,inherit 的值為下列值中的其一: enum { PTHREAD_INHERIT_SCHED, //線程調度屬性從創建者線程繼承 PTHREAD_EXPLICIT_SCHED //線程調度屬性設置為 attr 設置的屬性 };
假設在創建新的線程時,調用該函數將參數設置為 PTHREAD_INHERIT_SCHED 時,那么當改動進程的優先級時。該進程中繼承這個優先級而且還沒有改變其優先級的所 有線程也將會跟着改變優先級(也就是剛才那句話部分正確的原因)。
線程調度參數(實際上我們一般僅僅關心一個參數:線程的優先級,默覺得0)
int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param); int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param); //sched_param結構體 struct sched_param { int sched_priority; /* Scheduling priority */ };線程的並發級別
int pthread_setconcurrency(int new_level); int pthread_getconcurrency(void);
說明:並發級別僅在N:M線程模型中有效。設置並發級別,給內核一個提示:表示提供給定級別數量的核心線程來映射用戶線程是高效的(不過一個提示),默覺得0, 內核依照默認的方式進行並發。
我們來寫一個樣例來運用:
/** 查看線程默認屬性 **/ void printThreadAttr() { pthread_attr_t attr; pthread_attr_init(&attr); int detachstate; pthread_attr_getdetachstate(&attr, &detachstate); cout << "detach-state: " << (detachstate == PTHREAD_CREATE_JOINABLE ?"PTHREAD_CREATE_JOINABLE" : "PTHREAD_CREATE_DETACHED") << endl; size_t size; pthread_attr_getstacksize(&attr, &size); cout << "stack-size: " << size << endl; pthread_attr_getguardsize(&attr, &size); cout << "guard-size: " << size << endl; int scope; pthread_attr_getscope(&attr, &scope); cout << "scope: " << (scope == PTHREAD_SCOPE_SYSTEM ? "PTHREAD_SCOPE_SYSTEM" : "PTHREAD_SCOPE_PROCESS") << endl; int policy; pthread_attr_getschedpolicy(&attr, &policy); cout << "policy: "; switch (policy) { case SCHED_FIFO: cout << "SCHED_FIFO"; break; case SCHED_RR: cout << "SCHED_RR"; break; case SCHED_OTHER: cout << "SCHED_OTHER"; break; default: break; } cout << endl; int inheritsched; pthread_attr_getinheritsched(&attr, &inheritsched); cout << "inheritsched: " << (inheritsched == PTHREAD_INHERIT_SCHED ?
"PTHREAD_INHERIT_SCHED" : "PTHREAD_INHERIT_SCHED") << endl; struct sched_param param; pthread_attr_getschedparam(&attr, ¶m); cout << "scheduling priority: " << param.sched_priority << endl; cout << "concurrency: " << pthread_getconcurrency() << endl; pthread_attr_destroy(&attr); }

說明:
綁定屬性:
Linux中採用“一對一”的線程機制。也就是一個用戶線程相應一個內核線程。
綁定屬性就是指一個用戶線程固定地分配給一個內核線程。由於CPU時間片的調度是面向內核線程(也就是輕量級進程)的,因此具有綁定屬性的線程能夠保證在須要的時候總有一個內核線程與之相應。而與之相應的非綁定屬性就是指用戶線程和內核線程的關系不是始終固定的,而是由系統來控制分配的。
分離屬性:
分離屬性是用來決定一個線程以什么樣的方式來終止自己。在非分離情況下,當一個線程結束時,它所占用的系統資源並沒有被釋放。也就是沒有真正的終止。
僅僅有當pthread_join()函數返回時,創建的線程才干釋放自己占用的系統資源。而在分離屬性情況下,一個線程結束時馬上釋放它所占有的系統資源。這里要注意的一點是,假設設置一個線程的分離屬性。而這個線程執行又非常快,那么它非常可能在pthread_create()函數返回之前就終止了。它終止以后就可能將線程號和系統資源移交給其它的線程使用。