Linux c程式設計 執行緒屬性

2022-05-30 21:12:10 字數 3792 閱讀 8493

前面介紹了pthread_create函式,並且當時的例子中,傳入的引數都是空指標,而不是指向pthread_attr_t結構的指標。可以使用pthread_attr_t結構修改執行緒預設屬性,並把這些屬性與建立的執行緒聯絡起來。可以使用pthread_attr_init函式初始化pthread_attr_t結構。呼叫pthread_attr_init以後,pthread_attr_t結構所包含的內容就是作業系統實現支援的執行緒所有屬性的預設值。如果要修改其中個別屬性的值,需要呼叫其他的函式。

#include

int pthread_attr_init( pthread_attr_t *attr );

int pthread_attr_destroy( pthtread_attr_t *attr );

兩個函式的返回值都是:若成功則返回0,否則返回錯誤編號

如果要去除對pthread_attr_t結構的初始化,可以呼叫pthread_attr_destroy函式。如果pthread_attr_init實現時為屬性物件分配了動態記憶體空間,pthread_attr_destroy將會釋放該記憶體空間。除此之外,pthread_attr_destroy還會用無效的值初始化屬性物件,因此如果該屬性物件被誤用,將會導致pthread_create函式返回錯誤。

pthread_attr_t結構對應用程式是透明的,也就是說應用程式並不需要了解有關屬性物件內部結構的任何細節,因而可以增強應用程式的可移植性。posix.1沿用了這種模型,並且為查詢和設定每種屬性定義了獨立的函式

名稱

描述

detachstate

執行緒的分離狀態屬性

guardsize

執行緒棧末尾的警戒緩衝區大小(位元組數)

stackaddr

執行緒棧的最低位址

stacksize

執行緒棧的大小(位元組數)

如果在建立執行緒時就知道不需要了解執行緒的終止狀態,則可以修改pthread_attr_t結構中的detachstate執行緒屬性,讓執行緒以分離狀態啟動。可以使用pthread_attr_setdetachstate函式把執行緒屬性detachstate設定為下面的兩個合法值之一:設定為pthread_create_detached,以分離狀態啟動執行緒;或者設定為pthread_create_joinable,正常啟動執行緒,應用程式可以獲取執行緒的終止狀態。

#include
int pthread_attr_getdetachstate( const pthread_attr_t *restrict attr,
int *detachstate );
int pthread_attr_setdetachstate( pthread_attr_t *attr, int detachstate );
兩者的返回值都是:若成功則返回0,否則返回錯誤編號
可以呼叫pthread_attr_getdetachstate函式獲取當前的detachstate執行緒屬性,第二個引數所指向的整數用來儲存獲取到的detachstate屬性值:pthread_create_detached,或pthread_create_joinable)。
例項
程式:以分離狀態建立的執行緒
複製**
#include "apue.h"
#include
int
makethread(void *(*fn)(void *), void *arg)
這裡忽略了pthread_attr_destroy函式呼叫的返回值。在這種情況下,由於對執行緒屬性進行了合理的初始化,pthread_attr_destroy一般不會失敗。但是如果pthread_attr_destroy確實出現了失敗的情況,清理工作就會變得很困難:必須銷毀剛剛建立的執行緒,而這個執行緒可能已經執行,並且與pthread_attr_destroy函式可能是非同步執行的。忽略pthread_attr_destroy的錯誤返回可能出現的最壞的情況是:如果pthread_attr_init分配了記憶體空間,這些記憶體空間會被洩露。另一方面,如果pthread_attr_init成功地對執行緒屬性進行了初始化,但pthread_attr_destroy在做清理工作時卻出現了失敗,就沒有任何補救策略,因為執行緒屬性結構對應用程式來說是透明的,可以對執行緒屬性結構進行清理的唯一介面是pthread_attr_destroy,但它失敗了。
對於遵循posix標準的作業系統來說,並不一定要支援執行緒棧屬性,但是對於遵循xsi的系統,支援執行緒棧屬性就是必須的。可以在編譯階段使用_posix_thread_attr_stackaddr和_posix_attr_stacksize符號來檢查系統是否支援執行緒棧屬性,如果系統定義了這些符號,就說明它支援相應的執行緒棧屬性。也可以通過在執行階段把_sc_thread_attr_stackaddr和_sc_thread_attr_stacksize引數傳給sysconf函式,檢查系統對執行緒棧屬性的支援情況。
posix.1定義了執行緒棧屬性的一些操作介面。執行緒棧屬性的查詢和修改一般是通過較新的函式pthread_attr_getstack和pthread_attr_setstack來進行。
#include
int pthread_attr_getstack( const pthread_attr_t *restrict attr,
void **restrict stackaddr,
size_t *restrict stacksize );
int pthread_attr_setstack( const pthread_attr_t *attr,
void *stackaddr, size_t *stacksize );
兩者的返回值都是:若成功則返回0,否則返回錯誤編號
如果希望改變棧的預設大小,但又不想自己處理執行緒棧的分配問題,這時使用pthread_attr_setstacksize函式就非常有用。
執行緒屬性guardsize控制著執行緒棧末尾之後用以避免棧溢位的擴充套件記憶體的大小。這個屬性預設設定為pagesize個位元組。可以把guardsize執行緒屬性設為0,從而不允許屬性的這種特徵行為發生:在這種情況下不會提供警戒緩衝區。同樣地,如果對執行緒屬性stackaddr作了修改,系統就會假設我們會自己管理棧,並使警戒棧緩衝區機制無效,等同於把guardsize屬性設為0。
複製**
#include
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,否則返回錯誤編號
如果guardsize執行緒屬性被修改了,作業系統可能把它取為頁大小的整數倍。如果執行緒的棧指標溢位到警戒區域,應用程式就可能通過訊號接收到出錯資訊。

Linux C程式設計 執行緒操作執行緒屬性解析

執行緒屬性結構如下 typedef struct pthread attr t 屬性的預設值如下 屬性值 結果scope pthread scope process 新執行緒與程序中的其他執行緒發生競爭。detachstate pthread create joinable 執行緒退出後,保留完成狀...

linux C 多執行緒程式設計

1.solaris vs.linux posix 庫 solaris 庫 lib 執行緒 linux posix 庫 libp 執行緒 操作sema destroy sem destroy 銷毀訊號狀態。sema init sem init 初始化訊號。sema post sem post 增加訊號...

linux C 多執行緒程式設計

1.solaris vs.linux posix 庫 solaris 庫 lib 執行緒 linux posix 庫 libp 執行緒 操作sema destroy sem destroy 銷毀訊號狀態。sema init sem init 初始化訊號。sema post sem post 增加訊號...