linux下的线程属性
前面介紹了pthread_create函數,并且當時的例子中,傳入的參數都是空指針,而不是指向pthread_attr_t結構的指針。可以使用pthread_attr_t結構修改線程默認屬性,并把這些屬性與創建的線程聯系起來。可以使用pthread_attr_init函數初始化pthread_attr_t結構。調用pthread_attr_init以后,pthread_attr_t結構所包含的內容就是操作系統實現支持的線程所有屬性的默認值。如果要修改其中個別屬性的值,需要調用其他的函數。
#include <pthread.h>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_detach函數讓操作系統在線程退出時收回它所占用的資源。
如果在創建線程時就知道不需要了解線程的終止狀態,則可以修改pthread_attr_t結構中的detachstate線程屬性,讓線程以分離狀態啟動。可以使用pthread_attr_setdetachstate函數把線程屬性detachstate設置為下面的兩個合法值之一:設置為PTHREAD_CREATE_DETACHED,以分離狀態啟動線程;或者設置為PTHREAD_CREATE_JOINABLE,正常啟動線程,應用程序可以獲取線程的終止狀態。
#include <pthread.h>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 <pthread.h>int makethread(void *(*fn)(void *), void *arg){int?err;pthread_t tid;pthread_attr_t attr;err = pthread_attr_init(&attr);if(err != 0)return(err);err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);if(err == 0)err = pthread_create(&tid, &attr, fn, arg);pthread_attr_destroy(&attr);return(err);} 這里忽略了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 <pthread.h>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 <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,否則返回錯誤編號 如果guardsize線程屬性被修改了,操作系統可能把它取為頁大小的整數倍。如果線程的棧指針溢出到警戒區域,應用程序就可能通過信號接收到出錯信息。總結
以上是生活随笔為你收集整理的linux下的线程属性的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux下线程的一次性初始化
- 下一篇: linux 其他常用命令