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>
#include <stdio.h>
#include <errno.h>
#include <pthread.h>
static void* pthread_func_1 (void*);
static void* pthread_func_2 (void*);
int main (int argc, char** argv)
{
pthread_t pt_1 = 0;
pthread_t pt_2 = 0;
pthread_attr_t attr = {0};
int ret = 0;
pthread_attr_init (&attr); //屬性設定
pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM);
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
ret = pthread_create (&pt_1, &attr, pthread_func_1, NULL);
if (ret != 0)
{
perror ("pthread_1_create");
}
ret = pthread_create (&pt_2, NULL, pthread_func_2, NULL);
if (ret != 0)
{
perror ("pthread_2_create");
}
pthread_join (pt_2, NULL);
return 0;
}
static void* pthread_func_1 (void* data)
{
int i = 0;
for (; i < 6; i++)
{
printf ("This is pthread_1.\n");
if (i == 2)
{
pthread_exit (0);
}
}
return;
}
static void* pthread_func_2 (void* data)
{
int i = 0;
for (; i < 3; i ++)
{
printf ("This is pthread_2.\n");
}
return;
}
[uglychen@chenxun linux_chen]$ cat makefile
ALL= pthread
LIB= -lpthread
objects= linux1.o
$(ALL) : $(objects)
g++ -o $@ $(objects) $(LIB)
$(objects):%.o:%.cpp
$(CC) -c $< -o $@
.PHONY : clean
clean:
rm $(objects)
運作結果:
This is pthread1!
This is pthread2!
This is pthread2!
This is pthread2!
This is pthread1!
This is pthread1!