1. 線程屬性:
使用pthread_attr_t類型表示,我們需要對此結構體進行初始化,
初始化後使用,使用後還要進行去除初始化!
pthread_attr_init:初始化
pthread_attr_destory:去除初始化
#include <pthread.h>
int pthread_attr_init(pthread_attr_t *attr);
int pthread_attr_destroy(pthread_attr_t *attr);
若成功返回0,若失敗返回-1。
pthread_attr_init之後,pthread_t結構所包含的內容就是操作系統實現
支持的線程所有屬性的默認值。
如果pthread_attr_init實現時爲屬性對象分配了動態內存空間,
pthread_attr_destroy還會用無效的值初始化屬性對象,因此如果經
pthread_attr_destroy去除初始化之後的pthread_attr_t結構被
pthread_create函數調用,將會導致其返回錯誤。
線程屬性結構如下:
typedef struct
{
int detachstate; 線程的分離狀態
int schedpolicy; 線程調度策略
struct sched_param schedparam; 線程的調度參數
int inheritsched; 線程的繼承性
int scope; 線程的作用域
size_t guardsize; 線程棧末尾的警戒緩衝區大小
int stackaddr_set;
void * stackaddr; 線程棧的位置
size_t stacksize; 線程棧的大小
}pthread_attr_t;
下面主要討論此結構體!!!
2. 分離狀態:
線程的分離狀態決定一個線程以什麼樣的方式來終止自己。
我們已經在前面已經知道,在默認情況下線程是非分離狀態的,這種情況
下,原有的線程等待創建的線程結束。只有當pthread_join() 函數返回
時,創建的線程纔算終止,才能釋放自己佔用的系統資源。
分離線程沒有被其他的線程所等待,自己運行結束了,線程也就終止了,
馬上釋放系統資源。
通俗的說也就是:我們知道一般我們要等待(pthread_join)一個線程的結束,
主要是想知道它的結束狀態,否則等待一般是沒有什麼意義的!但是if有一
些線程的終止態我們壓根就不想知道,那麼就可以使用“分離”屬性,那麼我
們就無須等待管理,只要線程自己結束了,自己釋放src就可以咯!這樣更
方便!
#include <pthread.h>
int pthread_attr_getdetachstate(const pthread_attr_t * attr, int * detachstate);
int pthread_attr_setdetachstate(pthread_attr_t * attr, int detachstate);
參數:attr:線程屬性變量
detachstate:分離狀態屬性
若成功返回0,若失敗返回-1。
設置的時候可以有兩種選擇:
<1>.detachstate參數爲:PTHREAD_CREATE_DETACHED 分離狀態啓動
<2>.detachstate參數爲:PTHREAD_CREATE_JOINABLE 正常啓動線程
3. 線程的繼承性:
函數pthread_attr_setinheritsched和pthread_attr_getinheritsched分別用來設
置和得到線程的繼承性!
#include <pthread.h>
int pthread_attr_getinheritsched(const pthread_attr_t *attr,int *inheritsched);
int pthread_attr_setinheritsched(pthread_attr_t *attr,int inheritsched);
參數:
attr 線程屬性變量
inheritsched 線程的繼承性
若成功返回0,若失敗返回-1。
請注意:
繼承性決定調度的參數是從創建的進程中繼承還是使用在
schedpolicy和schedparam屬性中顯式設置的調度信息。
線程沒有默認的繼承值設置,所以如果關心線程的調度策略和參數,
只能手動設置!
可設置參數:
PTHREAD_INHERIT_SCHED: 新的線程繼承創建線程的策略和參數!
PTHREAD_EXPLICIT_SCHED:新的線程繼承策略和參數來自於
schedpolicy和schedparam屬性中顯式
設置的調度信息!
>>>>>: 下面補充線程調度策略和調度參數:
<1>.調度策略:
函數pthread_attr_setschedpolicy和pthread_attr_getschedpolicy分別用
來設置和得到線程的調度策略。
int pthread_attr_getschedpolicy(const pthread_attr_t *, int * policy)
int pthread_attr_setschedpolicy(pthread_attr_*, int policy)
參數:
attr 線程屬性變量
policy 調度策略
若成功返回0,若失敗返回-1。
所謂調度策略也就是我們之前在OS中所學過的那些調度算法:
SCHED_FIFO :先進先出
SCHED_RR :輪轉法
SCHED_OTHER :其他方法
SCHED_OTHER是不支持優先級使用的,而SCHED_FIFO和SCHED_RR
支持優先級的使用,他們分別爲1和99,數值越大優先級越高.
注意:
> 此處的SCHED_FIFO是允許被高優先級搶佔的!
> 也就是有高優先級的必須先運行
> SCHED_RR是設置一個時間片
> 當有SCHED_FIFO或SCHED_RR策賂的線程在一個條件變量
上等持或等持加鎖同一個互斥量時,它們將以優先級順序被喚
醒。即,如果一個低優先級的SCHED_FIFO線程和一個高優先
織的SCHED_FIFO線程都在等待鎖相同的互斥且,則當互斥量
被解鎖時,高優先級線程將總是被首先解除阻塞。
<2>.調度參數:
函數pthread_attr_getschedparam 和pthread_attr_setschedparam分別
用來設置和得到線程的調度參數。
int pthread_attr_getschedparam(const pthread_attr_t *,struct
sched_param *);
int pthread_attr_setschedparam(pthread_attr_t *,const struct
sched_param *);
參數:
attr 線程變量屬性
param sched_parm 結構體
若成功返回0,若失敗返回-1。
/usr/include /bits/sched.h
struct sched_param
{
int sched_priority; //!> 參數的本質就是優先級
};
注意:大的權值對應高的優先級!
系統支持的最大和最小的優先級值可以用函數:
sched_get_priority_max和sched_get_priority_min得到!
#include <pthread.h>
int sched_get_priority_max( int policy );
int sched_get_priority_min( int policy );
參數:max_: 系統支持的優先級的最小值
min_ : 系統支持的優先級的最大值
使用:max_ = sched_get_priority_max( policy );
min_ = sched_get_priority_min( policy );
注意參數是policy調用策略,也就是說對於不同的策略的值是不
一樣的!
附錄:來自
http://www.yuanma.org/data/2006/0823/article_1392.htm
policy = SCHED_OTHER
max_priority = 0
min_priority = 0
Show SCHED_FIFO of priority
max_priority = 99
min_priority = 1
Show SCHED_RR of priority
max_priority = 99
min_priority = 1
Show priority of current thread
priority = 0
3. 線程的作用域:
函數pthread_attr_setscope和pthread_attr_getscope分別
用來設置和得到線程的作用域。
#include <pthread.h>
int pthread_attr_getscope( const pthread_attr_t * attr, int * scope );
int pthread_attr_setscope( pthread_attr_t*, int scope );
參數:
attr 線程屬性變量
scope 線程的作用域
若成功返回0,若失敗返回-1。
作用域控制線程是否在進程內或在系統級上競爭資源,可能的值是
PTHREAD_SCOPE_PROCESS(進程內競爭資源)
PTHREAD_SCOPE_SYSTEM (系統級競爭資源)。
4. 線程堆棧的大小
函數pthread_attr_setstackaddr和pthread_attr_getstackaddr分別用來設置和得
到線程堆棧的位置。
int pthread_attr_getstacksize(const pthread_attr_t *,size_t * stacksize);
int pthread_attr_setstacksize(pthread_attr_t *attr ,size_t *stacksize);
參數:attr 線程屬性變量
stacksize 堆棧大小
若成功返回0,若失敗返回-1。
5. 線程堆棧的地址
#include <pthread.h>
int pthread_attr_getstackaddr(const pthread_attr_t *attr,void **stackaddf);
int pthread_attr_setstackaddr(pthread_attr_t *attr,void *stackaddr);
參數:attr 線程屬性變量
stackaddr 堆棧地址
若成功返回0,若失敗返回-1。
注意:pthread_attr_getstackaddr已經過期,現在使用的是:pthread_attr_getstack
6. 警戒緩衝區
函數pthread_attr_getguardsize和pthread_attr_setguardsize分別用來設置和得
到線程棧末尾的警戒緩衝區大小。
#include <pthread.h>
int pthread_attr_getguardsize(const pthread_attr_t *restrict attr,size_t *restrict
guardsize);
int pthread_attr_setguardsize(pthread_attr_t *attr ,size_t *guardsize);
若成功返回0,若失敗返回-1。
值得注意:
線程屬性guardsize控制着線程棧末尾之後以避免棧溢出的擴展內存
大小。這個屬性默認設置爲PAGESIZE個字節。可以把guardsize線
程屬性設爲0,從而不允許屬性的這種特徵行爲發生:在這種情況
下不會提供警戒緩存區。同樣地,如果對線程屬性stackaddr作了
修改,系統就會認爲我們會自己管理棧,並使警戒棧緩衝區機制無
效,等同於把guardsize線程屬性設爲0