在上一篇文章中,介紹了線程的建立和退出,以及相關函數的使用。其中pthread_create函數的第二個參數,是關於線程屬性的設定,這也是今天所有講述的。這些屬性主要包括邦定屬性、分離屬性、堆棧地址、堆棧大小、優先順序。其中系統預設的是非邦定、非分離、預設1M的堆棧、與父進程同樣層級的優先順序。在pthread_create中,把第二個參數設定為NULL的話,將採用預設的屬性配置。
(1)邦定屬性。
在LINUX中,採用的是“一對一”的線程機制。也就是一個使用者線程對應一個核心線程。邦定屬性就是指一個使用者線程固定地分配給一個核心線程,因為CPU時間片的調度是面向核心線程(輕量級進程)的,因此具有邦定屬性的線程可以保證在需要的時候總有一個核心線程與之對應,而與之對應的非邦定屬性就是指使用者線程和核心線程的關係不是始終固定的,而是由系統來分配。
(2)分離屬性。
分離屬性是決定以一個什麼樣的方式來終止自己。在非分離情況下,當一個線程結束時,它多佔用的線程沒有得到釋放,也就是沒有真正的終止,需要通過pthread_join來釋放資源。而在分離屬性情況下,一個線程結束時會立即釋放它所佔有的系統資源。但這裡有一點要注意的是,如果設定一個線程分離屬性,而這個線程又運行得非常快的話,那麼它很可能在pthread_create函數返回之前就終止了線程函數的運行,它終止以後就很有可能將線程號和系統資源移交給其他的線程使用,這時調用pthread_create的線程就得到錯誤的線程號。
這些屬性都是通過一些函數來完成的,通常先調用pthread_attr_init來初始化,之後來調用相應的屬性設定函數。
1、pthread_attr_init
功能: 對線程屬性變數的初始化。
標頭檔: <pthread.h>
函數原型: int pthread_attr_init (pthread_attr_t* attr);
函數傳入值:attr:線程屬性。
函數傳回值:成功: 0
失敗: -1
2、pthread_attr_setscope
功能: 設定線程綁定屬性。
標頭檔: <pthread.h>
函數原型: int pthread_attr_setscope (pthread_attr_t* attr, int scope);
函數傳入值:attr: 線程屬性。
scope:PTHREAD_SCOPE_SYSTEM(綁定)
PTHREAD_SCOPE_PROCESS(非綁定)
函數傳回值得:同1。
3、pthread_attr_setdetachstate
功能: 設定線程分離屬性。
標頭檔: <phread.h>
函數原型: int pthread_attr_setdetachstate (pthread_attr_t* attr, int detachstate);
函數傳入值:attr:線程屬性。
detachstate:PTHREAD_CREATE_DETACHED(分離)
PTHREAD_CREATE_JOINABLE(非分離)
函數傳回值得:同1。
4、pthread_attr_getschedparam
功能: 得到線程優先順序。
標頭檔: <pthread.h>
函數原型: int pthread_attr_getschedparam (pthread_attr_t* attr, struct sched_param* param);
函數傳入值:attr:線程屬性;
param:線程優先順序;
函數傳回值:同1。
5、pthread_attr_setschedparam
功能: 設定線程優先順序。
標頭檔: <pthread.h>
函數原型: int pthread_attr_setschedparam (pthread_attr_t* attr, struct sched_param* param);
函數傳入值:attr:線程屬性。
param:線程優先順序。
函數傳回值:同1。
函數實現:
#include <stdlib.h><br />#include <stdio.h><br />#include <errno.h><br />#include <pthread.h> </p><p>static void* pthread_func_1 (void*);<br />static void* pthread_func_2 (void*); </p><p>int main (int argc, char** argv)<br />{<br /> pthread_t pt_1 = 0;<br /> pthread_t pt_2 = 0;<br /> pthread_attr_t attr = {0};<br /> int ret = 0; </p><p> pthread_attr_init (&attr); //屬性設定<br /> pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM);<br /> pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); </p><p> ret = pthread_create (&pt_1, &attr, pthread_func_1, NULL);<br /> if (ret != 0)<br /> {<br /> perror ("pthread_1_create");<br /> } </p><p> ret = pthread_create (&pt_2, NULL, pthread_func_2, NULL);<br /> if (ret != 0)<br /> {<br /> perror ("pthread_2_create");<br /> } </p><p> pthread_join (pt_2, NULL); </p><p> return 0;<br />} </p><p>static void* pthread_func_1 (void* data)<br />{<br /> int i = 0; </p><p> for (; i < 6; i++)<br /> {<br /> printf ("This is pthread_1./n"); </p><p> if (i == 2)<br /> {<br /> pthread_exit (0);<br /> }<br /> } </p><p> return;<br />} </p><p>static void* pthread_func_2 (void* data)<br />{<br /> int i = 0; </p><p> for (; i < 3; i ++)<br /> {<br /> printf ("This is pthread_2./n");<br /> } </p><p> return;<br />}<br />
從上面案例中,可以得到這麼一個結果,就是線程一的線程函數一結束就自動釋放資源,線程二就得等到pthread_join來釋放系統資源。在下一篇文章中將介紹線程鎖。
~~END~~