線程屬性
前篇介紹了使用預設屬性建立線程的基本原理。本章論述如何在建立線程時設定
屬性。
注– 隻有pthreads 使用屬性和取消功能。本章中介紹的API 僅适用于POSIX 線程。除此
之外,Solaris 線程和pthreads 的功能大緻是相同的。
屬性對象
通過設定屬性,可以指定一種不同于預設行為的行為。使用
pthread_create(3C)
建立
線程時,或初始化同步變量時,可以指定屬性對象。預設值通常就足夠了。
屬性對象是不透明的,而且不能通過指派直接進行修改。系統提供了一組函數,用于
初始化、配置和銷毀每種對象類型。
初始化和配置屬性後,屬性便具有程序範圍的作用域。使用屬性時最好的方法即是在
程式執行早期一次配置好所有必需的狀态規範。然後,根據需要引用相應的屬性對
象。
使用屬性對象具有兩個主要優點。
■ 使用屬性對象可增加代碼可移植性。
即使支援的屬性可能會在實作之間有所變化,但您不需要修改用于建立線程實體的
函數調用。這些函數調用不需要進行修改,因為屬性對象是隐藏在接口之後的。
如果目标系統支援的屬性在目前系統中不存在,則必須顯式提供才能管理新的屬
性。管理這些屬性是一項非常容易的移植任務,因為隻需在明确定義的位置初始化
屬性對象一次即可。
■ 應用程式中的狀态規範已被簡化。
例如,假設程序中可能存在多組線程。每組線程都提供單獨的服務。每組線程都有
各自的狀态要求。
在應用程式執行初期的某一時間,可以針對每組線程初始化線程屬性對象。以後所
有線程的建立都會引用已經為這類線程初始化的屬性對象。初始化階段是簡單和局
部的。将來就可以快速且可靠地進行任何修改。
在程序退出時需要注意屬性對象。初始化對象時,将為該對象配置設定記憶體。必須将此内
存傳回給系統。pthreads 标準提供了用于銷毀屬性對象的函數調用。
初始化屬性
請使用
pthread_attr_init(3C)
将對象屬性初始化為其預設值。存儲空間是在執行期間
由線程系統配置設定的。
pthread_attr_init
文法
int pthread_attr_init(pthread_attr_t *tattr);
#include <pthread.h>
pthread_attr_t tattr;
int ret;
/* initialize an attribute to the default value */
ret = pthread_attr_init(&tattr);
表1 給出了屬性(tattr) 的預設值。
屬性 | 值 | 結果 |
---|---|---|
scope | | 新線程與程序中的其他線程發生競争。 |
detachstate | | 線程退出後,保留完成狀态和線程ID。 |
stackaddr | NULL | 新線程具有系統配置設定的棧位址。 |
stacksize | 新線程具有系統定義的棧大小。 | |
priority | 新線程的優先級為0。 | |
inheritsched | | 新線程不繼承父線程排程優先級。 |
schedpolicy | | 新線程對同步對象争用使用Solaris 定義的固定優先級。線程将一直運作,直到被搶占或者直到線程阻塞或停止為止。 |
pthread_attr_init
傳回值
pthread_attr_init()
成功完成後将傳回零。其他任何傳回值都表示出現了錯誤。如果
出現以下情況,該函數将失敗并傳回對應的值。
ENOMEM
描述: 如果未配置設定足夠的記憶體來初始化線程屬性對象,将傳回該值。
銷毀屬性
請使用
pthread_attr_destroy(3C)
删除初始化期間配置設定的存儲空間。屬性對象将會無
效。
pthread_attr_destroy
文法
int pthread_attr_destroy(pthread_attr_t *tattr);
#include <pthread.h>
pthread_attr_t tattr;
int ret;
/* destroy an attribute */
ret = pthread_attr_destroy(&tattr);
pthread_attr_destroy
傳回值
pthread_attr_destroy()
成功完成後将傳回零。其他任何傳回值都表示出現了錯誤。如
果出現以下情況,該函數将失敗并傳回對應的值。
EINVAL
描述: 訓示tattr 的值無效。
設定分離狀态
如果建立分離線程(
PTHREAD_CREATE_DETACHED
),則該線程一退出,便可重用其線程ID
和其他資源。如果調用線程不準備等待線程退出,請使用
pthread_attr_setdetachstate(3C)
。
pthread_attr_setdetachstate(3C)
文法
int pthread_attr_setdetachstate(pthread_attr_t *tattr,int detachstate);
#include <pthread.h>
pthread_attr_t tattr;
int ret;
/* set the thread detach state */
ret = pthread_attr_setdetachstate(&tattr,PTHREAD_CREATE_DETACHED);
如果使用
PTHREAD_CREATE_JOINABLE
建立非分離線程,則假設應用程式将等待線程完
成。也就是說,程式将對線程執行
pthread_join()
。
無論是建立分離線程還是非分離線程,在所有線程都退出之前,程序不會退出。
注– 如果未執行顯式同步來防止新建立的分離線程失敗,則線上程建立者從
pthread_create()
傳回之前,可以将其線程ID 重新配置設定給另一個新線程。
非分離線程在終止後,必須要有一個線程用join 來等待它。否則,不會釋放該線程的
資源以供新線程使用,而這通常會導緻記憶體洩漏。是以,如果不希望線程被等待,請
将該線程作為分離線程來建立。
示例1建立分離線程
#include <pthread.h>
pthread_attr_t tattr;
pthread_t tid;
void *start_routine;
void arg
int ret;
/* initialized with default attributes */
ret = pthread_attr_init (&tattr);
ret = pthread_attr_setdetachstate (&tattr,PTHREAD_CREATE_DETACHED);
ret = pthread_create (&tid, &tattr, start_routine, arg);
pthread_attr_setdetachstate
傳回值
pthread_attr_setdetachstate()
成功完成後将傳回零。其他任何傳回值都表示出現了
錯誤。如果出現以下情況,該函數将失敗并傳回對應的值。
EINVAL
描述: 訓示detachstate 或tattr 的值無效。
擷取分離狀态
請使用
pthread_attr_getdetachstate(3C)
檢索線程建立狀态(可以為分離或連接配接)。
pthread_attr_getdetachstate
文法
int pthread_attr_getdetachstate(const pthread_attr_t *tattr,
int *detachstate)
#include <pthread.h>
pthread_attr_t tattr;
int detachstate;
int ret;
/* get detachstate of thread */
ret = pthread_attr_getdetachstate (&tattr, &detachstate);
pthread_attr_getdetachstate
傳回值
pthread_attr_getdetachstate()
成功完成後将傳回零。其他任何傳回值都表示出現了
錯誤。如果出現以下情況,該函數将失敗并傳回對應的值。
EINVAL
描述: 訓示detachstate 的值為NULL 或tattr 無效。
設定棧溢出保護區大小
pthread_attr_setguardsize(3C)
可以設定attr 對象的guardsize。
pthread_attr_setguardsize(3C)
文法
#include <pthread.h>
int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
出于以下兩個原因,為應用程式提供了guardsize 屬性:
■ 溢出保護可能會導緻系統資源浪費。如果應用程式建立大量線程,并且已知這些線
程永遠不會溢出其棧,則可以關閉溢出保護區。通過關閉溢出保護區,可以節省系
統資源。
■ 線程在棧上配置設定大型資料結構時,可能需要較大的溢出保護區來檢測棧溢出。
guardsize 參數提供了對棧指針溢出的保護。如果建立線程的棧時使用了保護功能,則
實作會在棧的溢出端配置設定額外記憶體。此額外記憶體的作用與緩沖區一樣,可以防止棧指
針的棧溢出。如果應用程式溢出到此緩沖區中,這個錯誤可能會導緻SIGSEGV 信号被發
送給該線程。
如果guardsize 為零,則不會為使用attr 建立的線程提供溢出保護區。如果guardsize 大
于零,則會為每個使用attr 建立的線程提供大小至少為guardsize 位元組的溢出保護區。
預設情況下,線程具有實作定義的非零溢出保護區。
允許合乎慣例的實作,将guardsize 的值向上舍入為可配置的系統變量PAGESIZE 的倍
數。請參見sys/mman.h 中的
PAGESIZE
。如果實作将guardsize 的值向上舍入為
PAGESIZE
的倍數,則以guardsize(先前調用
pthread_attr_setguardsize()
時指定的溢出保護區
大小)為機關存儲對指定attr 的
pthread_attr_getguardsize()
的調用。
pthread_attr_setguardsize
傳回值
如果出現以下情況,
pthread_attr_setguardsize()
将失敗:
EINVAL
描述: 參數attr 無效,參數guardsize 無效,或參數guardsize 包含無效值。
擷取棧溢出保護區大小
pthread_attr_getguardsize(3C)
可以擷取attr 對象的guardsize。
pthread_attr_getguardsize
文法
#include <pthread.h>
int pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize);
允許一緻的實作将guardsize 中包含的值向上舍入為可配置系統變量PAGESIZE 的倍數。
請參見sys/mman.h 中的
PAGESIZE
。如果實作将guardsize 的值向上舍入為
PAGESIZE
的倍
數,則以guardsize(先前調用
pthread_attr_setguardsize()
時指定的溢出保護區大
小)為機關存儲對指定attr 的
pthread_attr_getguardsize()
的調用。
pthread_attr_getguardsize
傳回值
如果出現以下情況,
pthread_attr_getguardsize()
将失敗:
EINVAL
描述: 參數attr 無效,參數guardsize 無效,或參數guardsize 包含無效值。
設定範圍
請使用
pthread_attr_setscope(3C)
建立線程的争用範圍(
PTHREAD_SCOPE_SYSTEM
或
PTHREAD_SCOPE_PROCESS
)。使用
PTHREAD_SCOPE_SYSTEM
時,此線程将與系統中的所有
線程進行競争。使用
PTHREAD_SCOPE_PROCESS
時,此線程将與程序中的其他線程進行競
争。
注– 隻有在給定程序中才能通路這兩種線程類型。
pthread_attr_setscope
文法
int pthread_attr_setscope(pthread_attr_t *tattr,int scope);
#include <pthread.h>
pthread_attr_t tattr;
int ret;
/* bound thread */
ret = pthread_attr_setscope(&tattr, PTHREAD_SCOPE_SYSTEM);
/* unbound thread */
ret = pthread_attr_setscope(&tattr, PTHREAD_SCOPE_PROCESS);
本示例使用三個函數調用:用于初始化屬性的調用、用于根據預設屬性設定所有變體
的調用,以及用于建立pthreads 的調用。
#include <pthread.h>
pthread_attr_t attr;
pthread_t tid;
void start_routine;
void arg;
int ret;
/* initialized with default attributes */
ret = pthread_attr_init (&tattr);
/* BOUND behavior */
ret = pthread_attr_setscope(&tattr, PTHREAD_SCOPE_SYSTEM);
ret = pthread_create (&tid, &tattr, start_routine, arg);
pthread_attr_setscope
傳回值
pthread_attr_setscope()
成功完成後将傳回零。其他任何傳回值都表示出現了錯誤。
如果出現以下情況,該函數将失敗并傳回對應的值。
EINVAL
描述: 嘗試将tattr 設定為無效的值。
擷取範圍
請使用
pthread_attr_getscope(3C)
檢索線程範圍。
pthread_attr_getscope
文法
int pthread_attr_getscope(pthread_attr_t *tattr, int *scope);
#include <pthread.h>
pthread_attr_t tattr;
int scope;
int ret;
/* get scope of thread */
ret = pthread_attr_getscope(&tattr, &scope);
pthread_attr_getscope
傳回值
pthread_attr_getscope()
成功完成後将傳回零。其他任何傳回值都表示出現了錯誤。
如果出現以下情況,該函數将失敗并傳回對應的值。
EINVAL
描述: scope 的值為NULL 或tattr 無效。
設定線程并行級别
針對标準符合性提供了
pthread_setconcurrency(3C)
。應用程式使用
pthread_setconcurrency()
通知系統其所需的并發級别。對于Solaris 9 發行版中引入的
線程實作,此接口沒有任何作用,所有可運作的線程都将被連接配接到LWP。
pthread_setconcurrency
文法
#include <pthread.h>
int pthread_setconcurrency(int new_level);
pthread_setconcurrency
傳回值
如果出現以下情況,
pthread_setconcurrency()
将失敗:
EINVAL
描述: new_level 指定的值為負數。
EAGAIN
描述: new_level 指定的值将導緻系統資源不足。
擷取線程并行級别
pthread_getconcurrency(3C)
傳回先前調用
pthread_setconcurrency()
時設定的值。
pthread_getconcurrency
文法
#include <pthread.h>
int pthread_getconcurrency(void);
如果以前未調用
pthread_setconcurrency()
函數,則
pthread_getconcurrency()
将傳回
零。
pthread_getconcurrency
傳回值
pthread_getconcurrency()
始終會傳回先前調用
pthread_setconcurrency()
時設定的并
發級别。如果從未調用
pthread_setconcurrency()
,則
pthread_getconcurrency()
将返
回零。
設定排程政策
請使用
pthread_attr_setschedpolicy(3C)
設定排程政策。POSIX 标準指定
SCHED_FIFO
(先入先出)、
SCHED_RR
(循環)或
SCHED_OTHER(
實作定義的方法)的排程政策屬
性。
pthread_attr_setschedpolicy(3C)
文法
int pthread_attr_setschedpolicy(pthread_attr_t *tattr, int policy);
#include <pthread.h>
pthread_attr_t tattr;
int policy;
int ret;
/* set the scheduling policy to SCHED_OTHER */
ret = pthread_attr_setschedpolicy(&tattr, SCHED_OTHER);
■
SCHED_FIFO
如果調用程序具有有效的使用者ID 0,則争用範圍為系統(
PTHREAD_SCOPE_SYSTEM
) 的
先入先出線程屬于實時(RT) 排程類。如果這些線程未被優先級更高的線程搶占,則
會繼續處理該線程,直到該線程放棄或阻塞為止。對于具有程序争用範圍
(
PTHREAD_SCOPE_PROCESS
) 的線程或其調用程序沒有有效使用者ID 0 的線程,請使用
SCHED_FIFO
。
SCHED_FIFO
基于TS 排程類。
■
SCHED_RR
如果調用程序具有有效的使用者ID 0,則争用範圍為系統(
PTHREAD_SCOPE_SYSTEM
) 的
循環線程屬于實時(RT) 排程類。如果這些線程未被優先級更高的線程搶占,并且這
些線程沒有放棄或阻塞,則在系統确定的時間段内将一直執行這些線程。對于具有
程序争用範圍(
PTHREAD_SCOPE_PROCES
) 的線程,請使用
SCHED_RR
(基于TS 排程
類)。此外,這些線程的調用程序沒有有效的使用者ID 0。
SCHED_FIFO
和
SCHED_RR
在POSIX 标準中是可選的,而且僅用于實時線程。
pthread_attr_setschedpolicy
傳回值
pthread_attr_setschedpolicy()
成功完成後将傳回零。其他任何傳回值都表示出現了
錯誤。如果出現以下任一情況,該函數将失敗并傳回對應的值。
EINVAL
描述: 嘗試将tattr 設定為無效的值。
ENOTSUP
描述: 嘗試将該屬性設定為不受支援的值。
擷取排程政策
請使用
pthread_attr_getschedpolicy(3C)
檢索排程政策。
pthread_attr_getschedpolicy
文法
int pthread_attr_getschedpolicy(pthread_attr_t *tattr, int *policy);
#include <pthread.h>
pthread_attr_t tattr;
int policy;
int ret;
/* get scheduling policy of thread */
ret = pthread_attr_getschedpolicy (&tattr, &policy);
pthread_attr_getschedpolicy
傳回值
pthread_attr_getschedpolicy()
成功完成後将傳回零。其他任何傳回值都表示出現了
錯誤。如果出現以下情況,該函數将失敗并傳回對應的值。
EINVAL
描述: 參數policy 為NULL 或tattr 無效。
設定繼承的排程政策
請使用
pthread_attr_setinheritsched(3C)
設定繼承的排程政策。
pthread_attr_setinheritsched
文法
int pthread_attr_setinheritsched(pthread_attr_t *tattr, int inherit);
#include <pthread.h>
pthread_attr_t tattr;
int inherit;
int ret;
/* use the current scheduling policy */
ret = pthread_attr_setinheritsched(&tattr, PTHREAD_EXPLICIT_SCHED);
inherit 值
PTHREAD_INHERIT_SCHED
表示建立的線程将繼承建立者線程中定義的排程策
略。将忽略在
pthread_create()
調用中定義的所有排程屬性。如果使用預設值
PTHREAD_EXPLICIT_SCHED
,則将使用
pthread_create()
調用中的屬性。
pthread_attr_setinheritsched
傳回值
pthread_attr_setinheritsched()
成功完成後将傳回零。其他任何傳回值都表示出現了
錯誤。如果出現以下任一情況,該函數将失敗并傳回對應的值。
EINVAL
描述: 嘗試将tattr 設定為無效的值。
ENOTSUP
描述: 嘗試将屬性設定為不受支援的值。
擷取繼承的排程政策
pthread_attr_getinheritsched(3C)
将傳回由
pthread_attr_setinheritsched()
設定的
排程政策。
pthread_attr_getinheritsched
文法
int pthread_attr_getinheritsched(pthread_attr_t *tattr, int *inherit);
#include <pthread.h>
pthread_attr_t tattr;
int inherit;
int ret;
/* get scheduling policy and priority of the creating thread */
ret = pthread_attr_getinheritsched (&tattr, &inherit);
pthread_attr_getinheritsched
傳回值
pthread_attr_getinheritsched()
成功完成後将傳回零。其他任何傳回值都表示出現了
錯誤。如果出現以下情況,該函數将失敗并傳回對應的值。
EINVAL
描述: 參數inherit 為NULL 或tattr 無效。
設定排程參數
pthread_attr_setschedparam(3C)
可以設定排程參數。
pthread_attr_setschedparam
文法
int pthread_attr_setschedparam(pthread_attr_t *tattr,
const struct sched_param *param);
#include <pthread.h>
pthread_attr_t tattr;
int newprio;
sched_param param;
newprio = ;
/* set the priority; others are unchanged */
param.sched_priority = newprio;
/* set the new scheduling param */
ret = pthread_attr_setschedparam (&tattr, ¶m);
排程參數是在param 結構中定義的。僅支援優先級參數。新建立的線程使用此優先級運
行。
pthread_attr_setschedparam
傳回值
pthread_attr_setschedparam()
成功完成後将傳回零。其他任何傳回值都表示出現了錯
誤。如果出現以下情況,該函數将失敗并傳回對應的值。
EINVAL
描述: param 的值為NULL 或tattr 無效。
可以采用兩種方式之一來管理pthreads 優先級:
■ 建立子線程之前,可以設定優先級屬性
■ 可以更改父線程的優先級,然後再将該優先級改回來
擷取排程參數
pthread_attr_getschedparam(3C)
将傳回由
pthread_attr_setschedparam()
定義的排程
參數。
pthread_attr_getschedparam
文法
int pthread_attr_getschedparam(pthread_attr_t *tattr,
const struct sched_param *param);
#include <pthread.h>
pthread_attr_t attr;
struct sched_param param;
int ret;
/* get the existing scheduling param */
ret = pthread_attr_getschedparam (&tattr, ¶m);
使用指定的優先級建立線程
建立線程之前,可以設定優先級屬性。将使用在
sched_param
結構中指定的新優先級創
建子線程。此結構還包含其他排程資訊。
建立子線程時建議執行以下操作:
■ 擷取現有參數
■ 更改優先級
■ 建立子線程
■ 恢複原始優先級
建立具有優先級的線程的示例
示例2 給出了使用不同于其父線程優先級的優先級建立子線程的示例。
示例2建立具有優先級的線程
#include <pthread.h>
#include <sched.h>
pthread_attr_t tattr;
pthread_t tid;
int ret;
int newprio = ;
sched_param param;
/* initialized with default attributes */
ret = pthread_attr_init (&tattr);
/* safe to get existing scheduling param */
ret = pthread_attr_getschedparam (&tattr, ¶m);
/* set the priority; others are unchanged */
param.sched_priority = newprio;
/* setting the new scheduling param */
ret = pthread_attr_setschedparam (&tattr, ¶m);
/* with new priority specified */
ret = pthread_create (&tid, &tattr, func, arg);
pthread_attr_getschedparam
傳回值
pthread_attr_getschedparam()
成功完成後将傳回零。其他任何傳回值都表示出現了錯
誤。如果出現以下情況,該函數将失敗并傳回對應的值。
EINVAL
描述: param 的值為NULL 或tattr 無效。
設定棧大小
pthread_attr_setstacksize(3C)
可以設定線程棧大小。
pthread_attr_setstacksize
文法
int pthread_attr_setstacksize(pthread_attr_t *tattr,
size_t size);
#include <pthread.h>
pthread_attr_t tattr;
size_t size;
int ret;
size = (PTHREAD_STACK_MIN + );
/* setting a new size */
ret = pthread_attr_setstacksize(&tattr, size);
stacksize 屬性定義系統配置設定的棧大小(以位元組為機關)。size 不應小于系統定義的最小
棧大小
size 包含新線程使用的棧的位元組數。如果size 為零,則使用預設大小。在大多數情況
下,零值最适合。
PTHREAD_STACK_MIN
是啟動線程所需的棧空間量。此棧空間沒有考慮執行應用程式代碼
所需的線程例程要求。
pthread_attr_setstacksize
傳回值
pthread_attr_setstacksize()
成功完成後将傳回零。其他任何傳回值都表示出現了錯
誤。如果出現以下情況,該函數将失敗并傳回對應的值。
EINVAL
描述: size 值小于
PTHREAD_STACK_MIN
,或超出了系統強加的限制,或者tattr 無效。
擷取棧大小
pthread_attr_getstacksize(3C)
将傳回由
pthread_attr_setstacksize()
設定的棧大
小。
pthread_attr_getstacksize
文法
int pthread_attr_getstacksize(pthread_attr_t *tattr,
size_t *size);
#include <pthread.h>
pthread_attr_t tattr;
size_t size;
int ret;
/* getting the stack size */
ret = pthread_attr_getstacksize(&tattr, &size);
pthread_attr_getstacksize
傳回值
pthread_attr_getstacksize()
成功完成後将傳回零。其他任何傳回值都表示出現了錯
誤。如果出現以下情況,該函數将失敗并傳回對應的值。
EINVAL
描述: tattr 無效。
關于棧
通常,線程棧是從頁邊界開始的。任何指定的大小都被向上舍入到下一個頁邊界。不
具備通路權限的頁将被附加到棧的溢出端。大多數棧溢出都會導緻将
SIGSEGV
信号發送
到違例線程。将直接使用調用方配置設定的線程棧,而不進行修改。指定棧時,還應使用
PTHREAD_CREATE_JOINABLE
建立線程。在該線程的
pthread_join(3C)
調用傳回之前,不會釋放該棧。在該線程終止之前,不會釋放該線程的棧。
了解這類線程是否已終止的唯一可靠方式是使用
pthread_join(3C)
。
為線程配置設定棧空間
一般情況下,不需要為線程配置設定棧空間。系統會為每個線程的棧配置設定1MB(對于32 位
系統)或2MB(對于64 位系統)的虛拟記憶體,而不保留任何交換空間。系統将使用
mmap()
的
MAP_NORESERVE
選項來進行配置設定。
系統建立的每個線程棧都具有紅色區域。系統通過将頁附加到棧的溢出端來建立紅色
區域,進而捕獲棧溢出。此類頁無效,而且會導緻記憶體(通路時)故障。紅色區域将
被附加到所有自動配置設定的棧,無論大小是由應用程式指定,還是使用預設大小。
注– 對于庫調用和動态連結,運作時棧要求有所變化。應絕對确定,指定的棧滿足庫調
用和動态連結的運作時要求。
極少數情況下需要指定棧和/或棧大小。甚至專家也很難了解是否指定了正确的大小。
甚至符合ABI 标準的程式也不能靜态确定其棧大小。棧大小取決于執行中特定運作時
環境的需要。
生成自己的棧
指定線程棧大小時,必須考慮被調用函數以及每個要調用的後續函數的配置設定需求。需
要考慮的因素應包括調用序列需求、局部變量和資訊結構。
有時,您需要與預設棧略有不同的棧。典型的情況是,線程需要的棧大小大于預設棧
大小。而不太典型的情況是,預設大小太大。您可能正在使用不足的虛拟記憶體建立數
千個線程,進而處理數千個預設線程棧所需的數千兆位元組的棧空間。
對棧的最大大小的限制通常較為明顯,但對其最小大小的限制如何呢?必須存在足夠
的棧空間來處理推入棧的所有棧幀,及其局部變量等。
要擷取對棧大小的絕對最小限制,請調用宏
PTHREAD_STACK_MIN
。
PTHREAD_STACK_MIN
宏
将針對執行NULL 過程的線程傳回所需的棧空間量。有用的線程所需的棧大小大于最小
棧大小,是以縮小棧大小時應非常謹慎。
#include <pthread.h>
pthread_attr_t tattr;
pthread_t tid;
int ret;
size_t size = PTHREAD_STACK_MIN + ;
/* initialized with default attributes */
ret = pthread_attr_init(&tattr);
/* setting the size of the stack also */
ret = pthread_attr_setstacksize(&tattr, size);
/* only size specified in tattr*/
ret = pthread_create(&tid, &tattr, start_routine, arg);
設定棧位址和大小
pthread_attr_setstack(3C)
可以設定線程棧位址和大小。
pthread_attr_setstack(3C)
文法
int pthread_attr_setstack(pthread_attr_t *tattr,void *stackaddr,
size_t stacksize);
#include <pthread.h>
pthread_attr_t tattr;
void *base;
size_t size;
int ret;
base = (void *) malloc(PTHREAD_STACK_MIN + );
/* setting a new address and size */
ret = pthread_attr_setstack(&tattr, base,PTHREAD_STACK_MIN + );
stackaddr 屬性定義線程棧的基準(低位位址)。stacksize 屬性指定棧的大小。如果将
stackaddr 設定為非空值,而不是預設的NULL,則系統将在該位址初始化棧,假設大小
為stacksize。
base 包含新線程使用的棧的位址。如果base 為NULL,則
pthread_create(3C)
将為大小
至少為stacksize 位元組的新線程配置設定棧。
pthread_attr_setstack(3C)
傳回值
pthread_attr_setstack()
成功完成後将傳回零。其他任何傳回值都表示出現了錯誤。
如果出現以下情況,該函數将失敗并傳回對應的值。
EINVAL
描述: base 或tattr 的值不正确。stacksize 的值小于
PTHREAD_STACK_MIN
。
以下示例說明如何使用自定義棧位址和大小來建立線程。
#include <pthread.h>
pthread_attr_t tattr;
pthread_t tid;
int ret;
void *stackbase;
size_t size;
/* initialized with default attributes */
ret = pthread_attr_init(&tattr);
/* setting the base address and size of the stack */
ret = pthread_attr_setstack(&tattr, stackbase,size);
/* address and size specified */
ret = pthread_create(&tid, &tattr, func, arg);
擷取棧位址和大小
pthread_attr_getstack(3C)
将傳回由
pthread_attr_setstack()
設定的線程棧位址和大
小。
pthread_attr_getstack
文法
int pthread_attr_getstack(pthread_attr_t *tattr,void * *stackaddr,
size_t *stacksize);
#include <pthread.h>
pthread_attr_t tattr;
void *base;
size_t size;
int ret;
/* getting a stack address and size */
ret = pthread_attr_getstackaddr (&tattr, &base, &size);
pthread_attr_getstack
傳回值
pthread_attr_getstackaddr()
成功完成後将傳回零。其他任何傳回值都表示出現了錯
誤。如果出現以下情況,該函數将失敗并傳回對應的值。
EINVAL
描述: tattr 的值不正确。