歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Unix知識 >> Unix基礎知識 >> UNIX環境高級編程:線程屬性

UNIX環境高級編程:線程屬性

日期:2017/3/3 15:19:39   编辑:Unix基礎知識

pthread_attr_t 的缺省屬性值

1、初始化一個線程對象的屬性

int pthread_attr_init(pthread_attr_t *attr);

返回值:若是成功返回0,否則返回錯誤的編號

形 參: attr 指向一個線程屬性的指針

說 明:Posix線程中的線程屬性pthread_attr_t主要包括scope屬性、detach屬性、堆棧地址、堆棧大小、優先級。

pthread_attr_init實現時為屬性對象分配了動態內存空間。

線程屬性結構如下:

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、銷毀一個線程屬性對象

int pthread_attr_destroy(pthread_attr_t *attr);

返回值:若是成功返回0,否則返回錯誤的編號

形 參:attr 指向一個線程屬性的指針

說 明:如果pthread_attr_init實現時為屬性對象分配了動態內存空間,pthread_attr_destroy將會釋放該內存空間。

經pthread_attr_destroy去除初始化之後的pthread_attr_t結構被pthread_create函數調用,將會導致其返回錯誤。

3、獲取線程分離狀態屬性.

int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate);

返回值:若是成功返回0,否則返回錯誤的編號

形 參: attr 指向一個線程屬性的指針

detachstate 保存返回的分離狀態屬性,有兩個取值:

PTHREAD_CREATE_DETACHED(分離)

PTHREAD_CREATE_JOINABLE(非分離)

說 明:獲取線程分離狀態屬性

4、修改線程分離狀態屬性

int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);

如果對現有的某個線程的終止狀態不感興趣的話,可以使用pthread_detach函數讓操作系統在線程退出時收回它所占有的資源。如果在創建線程之前就知道不需要了解線程的終止狀態,則可以修改pthread_attr_t結構中的detachstate線程屬性,讓線程以分離狀態啟動。其中pthread_detach函數時在線程創建之後設置分離屬性的。

返回值:若是成功返回0,否則返回錯誤的編號

形 參:attr 指向一個線程屬性的指針

detachstat 有兩個取值:

PTHREAD_CREATE_DETACHED(分離)

PTHREAD_CREATE_JOINABLE(非分離)

說 明:所有的Pthreads系統都支持detachstate屬性,該屬性的值可以是PTHREAD_CREATE_DETACHED(分離)或PTHREAD_CREATE_JOINABLE(非分離)。默認的,線程被創建為非分離,即意味著由pthread_create創建的該線程ID能被用來與線程連接並獲得它的返回值,或取消它。

5、獲取線程的堆棧信息(棧地址和棧大小)

int pthread_attr_getstack(pthread_attr_t *attr, void **stackaddr, size_t *stacksize);

返回值:若是成功返回0,否則返回錯誤的編號

形 參:attr 指向一個線程屬性的指針

stackaddr 返回獲取的棧地址

stacksize 返回獲取的棧大小

說 明:獲取線程的堆棧地址和大小

6、設置線程的堆棧信息(棧地址和棧大小)

int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize);

返回值:若是成功返回0,否則返回錯誤的編號

形 參:attr 指向一個線程屬性的指針

stackaddr 線程的堆棧地址(低位地址):應該是可移植的,對齊頁邊距的可以用posix_memalign來進行獲取。如果將 stackaddr 設置為非空值,而不是缺省的 NULL,則系統將在該地址初始化棧,假設大小為 stacksize。

stacksize 線程的堆棧大小:應該是頁大小的整數倍

說 明:設置堆棧區,將導致pthread_attr_setguardsize失效。

試用場合:對進程來說,虛擬地址空間的大小是固定的,進程中只有一個棧,所以它的大小通常不是問題。但對線程來說,同樣大小的虛擬地址空間必須被所有的線程棧共享。如果應用程序使用了太多的線程,致使線程棧的累計大小超過了可用的虛擬地址空間,這時就需要減少線程默認的棧大小。另一方面,如果線程調用的函數分配了大量的自動變量或者調用的函數涉及很深的棧幀,那麼這時需要的棧的大小可能要比默認的大。

注意:stackaddr 線程屬性被定義為棧的內存單元的最低地址,但這並不是必然是棧的開始位置。對於某些處理器結構來說,棧是從高地址向低地址方向伸展的,那麼stackaddr 線程屬性就是棧的結尾而不是開始位置。

7、獲取線程堆棧地址

int pthread_attr_getstackaddr(pthread_attr_t *attr, void **stackaddr);

返回值:若是成功返回0,否則返回錯誤的編號

形 參:attr 指向一個線程屬性的指針

stackaddr 返回獲取的棧地址

說 明:函數已過時,一般用pthread_attr_getstack來代替

8、設置線程堆棧地址

int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr);

返回值:若是成功返回0,否則返回錯誤的編號

形 參:attr 指向一個線程屬性的指針

stackaddr 設置線程堆棧地址

說 明:函數已過時,一般用pthread_attr_setstack來代替。

查看本欄目更多精彩內容:http://www.bianceng.cn/OS/unix/

9、獲取線程堆棧大小

int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *stacksize);

返回值:若是成功返回0,否則返回錯誤的編號

形 參:attr 指向一個線程屬性的指針

stacksize 返回線程的堆棧大小

說 明:獲取線程堆棧大小。設置堆棧大小不是可移植的。Pthreads定義PTHREAD_STACK_MIN標志,指定每個線程要求的最小棧大小,包含#include <limits.h>後可以通過打印其值查看。命令:#ulimit -s或者#ulimit -a其中stack size項表示堆棧大小。#ulimit -s value用來重新設置stack大小。默認為8M,最小16384字節。

注意:通常,線程棧是從頁邊界開始的。任何指定的大小都被向上捨入到下一個頁邊界。不具備訪問權限的頁將被附加到棧的溢出端。大多數棧溢出都會導致將 SIGSEGV 信號發送到違例線程(注意可以參考《UNIX環境高級編程——存儲映射I/O(mmap函數)》)。將直接使用調用方分配的線程棧,而不進行修改。指定棧時,還應用 PTHREAD_CREATE_JOINABLE 創建線程。在該線程的 pthread_join調用返回之前,不會釋放該棧。在該線程終止之前,不會釋放該線程的棧。一般情況下,不需要為線程分配棧空間。系統會為每個線程的棧分配 1 MB(對於 32 位系統)或 2 MB(對於 64 位系統)的虛擬內存,而不保留任何交換空間。系統將使用 mmap() 的 MAP_NORESERVE 選項來進行分配。極少數情況下需要指定棧和/或棧大小。甚至專家也很難了解是否指定了正確的大小。

10、設置線程堆棧大小

int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);

返回值:若是成功返回0,否則返回錯誤的編號

形 參:attr 指向一個線程屬性的指針

stacksize 線程的堆棧大小(以字節為單位):應該是頁大小的整數倍。(以字節為單位)。stacksize不應小於系統定義的最小棧大小。stacksize包含新線程使用的棧的字節數。如果 stacksize為零,則使用缺省大小。在大多數情況下,零值最適合。

11、獲取線程的棧溢出保護區大小

int pthread_attr_getguardsize(pthread_attr_t *attr, size_t *guardsize);

返回值:若是成功返回0,否則返回錯誤的編號

形 參: attr 指向一個線程屬性的指針

guardsize 返回獲取的棧保護區大小

說 明:獲取線程的棧保護區大小。

出於以下兩個原因,為應用程序提供了 guardsize 屬性:

溢出保護可能會導致系統資源浪費。如果應用程序創建大量線程,並且已知這些線程永遠不會溢出其棧,則可以關閉溢出保護區。通過關閉溢出保護區,可以節省系統資源。

線程在棧上分配大型數據結構時,可能需要較大的溢出保護區來檢測棧溢出。

guardsize 參數提供了對棧指針溢出的保護。如果創建線程的棧時使用了保護功能,則實現會在棧的溢出端分配額外內存。此額外內存的作用與緩沖區一樣,可以防止棧指針的棧溢出。如果應用程序溢出到此緩沖區中,這個錯誤可能會導致 SIGSEGV 信號被發送給該線程。

12、設置線程的棧溢出保護區大小

int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);

返回值:若是成功返回0,否則返回錯誤的編號

形 參:attr 指向一個線程屬性的指針

guardsize 線程的棧保護區大小

說 明:參數提供了對棧指針溢出的保護。

如果 guardsize 為零,則不會為使用 attr 創建的線程提供溢出保護區。

如果 guardsize 大於零,則會為每個使用attr 創建的線程提供大小至少為 guardsize 字節的溢出保護區。缺省情況下,線程具有實現定義的非零溢出保護區。將 guardsize 的值向上捨入為可配置的系統變量 PAGESIZE 的倍數。請參見 sys/mman.h 中的PAGESIZE(4096字節)。

注意:線程屬性guardsize 控制著線程棧末尾之後用以避免溢出的擴展內存的大小。這個屬性默認設置為PAGESIZE個字節。可以把guardsize線程屬性設為0,從而不允許屬性的這種屬性的行為發生:在這種情況下不會提供警戒緩沖區。同樣地,如果對線程屬性stackaddr(pthread_attr_setstack/pthread_attr_setstackaddr 函數)作了修改,系統就會假設我們會自己管理棧,並使警戒緩沖機制無效,等同於把guardsize線程屬性設為0.

作者:csdn博客 ctthuangcheng

Copyright © Linux教程網 All Rights Reserved