創(chuàng)建線程和結(jié)束線程
交流群728483370,一起學(xué)習(xí)加油!
(1)線程創(chuàng)建函數(shù)
int?pthread_create?(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
功能:創(chuàng)建一個(gè)具有指定參數(shù)的線程。
形參:thread是要?jiǎng)?chuàng)建的線程的線程ID指針。
pthread_t類型的定義是typedef unsigned long int pthread_t;(打印時(shí)要使用%lu或%u方式)。
attr:創(chuàng)建線程時(shí)的線程屬性(設(shè)置NULL表示使用默認(rèn)線程屬性)。
start_routine:指向的是新線程將運(yùn)行的函數(shù)。線程一旦被創(chuàng)建好,內(nèi)核就可以調(diào)度內(nèi)核線程來執(zhí)行start_routine函數(shù)指針?biāo)赶虻暮瘮?shù)了。
arg:指向的是運(yùn)行函數(shù)的形參。
返回值:若是成功建立線程返回0,否則返回錯(cuò)誤的編號(hào)。
(2)等待線程結(jié)束函數(shù)
int?pthread_join(pthread_t thread, void **retval);
功能:這個(gè)函數(shù)是一個(gè)線程阻塞的函數(shù),調(diào)用它的函數(shù)將一直等待到被等待的線程結(jié)束為止,當(dāng)函數(shù)返回時(shí),被等待線程的資源被收回
形參:thread是被等待的線程標(biāo)識(shí)符。
retval:一個(gè)用戶定義的指針,它可以用來存儲(chǔ)被等待線程的返回值。
返回值:成功返回0,否則返回錯(cuò)誤的編號(hào)。
錯(cuò)誤碼:
①EDEADLK:可能引起死鎖,比如兩個(gè)線程互相針對(duì)對(duì)方調(diào)用pthread_join,或者線程對(duì)自身調(diào)用pthread_join。
②EINVAL:目標(biāo)線程是不可回收的,或者已經(jīng)有其他線程在回收目標(biāo)線程。
③ESRCH:目標(biāo)線程不存在。
(3)線程退出函數(shù)
void?pthread_exit(void *retval);
功能:線程函數(shù)在結(jié)束時(shí)調(diào)用此函數(shù),以確保安全、干凈地退出。
形參:retval是函數(shù)的返回指針,只要pthread_join中的第二個(gè)參數(shù)retval不是NULL,這個(gè)值將被傳遞給retval。pthread_exit函數(shù)通過retval參數(shù)向線程的回收者傳遞其退出信息。他執(zhí)行完之后不會(huì)返回到調(diào)用者,而且永遠(yuǎn)不會(huì)失敗。
(4)線程取消函數(shù)
int?pthread_cancel(pthread_t thread);
功能:取消某個(gè)線程的執(zhí)行。
形參:thread是要取消線程的標(biāo)識(shí)符ID。
返回值:若是成功返回0,否則返回錯(cuò)誤的編號(hào)。
但是,接收到取消請(qǐng)求的目標(biāo)線程可以決定是否允許被取消以及如何取消,這分別由如下兩個(gè)函數(shù)完成。
int pthread_setcancelstate(int state, int *oldstate);
int pthread_setcanceltype(int type, int *oldtype);
這兩個(gè)函數(shù)的第一個(gè)參數(shù)分別用于設(shè)置線程的取消狀態(tài)(是否允許取消)和取消類型(如何取消),第二個(gè)參數(shù)則分別記錄線程原來的取消狀態(tài)和取消類型。
state參數(shù)有兩個(gè)可選值:
PTHREAD_CANCEL_CNABLE,允許線程被取消。它是線程被創(chuàng)建時(shí)的默認(rèn)取消狀態(tài)。
PTHREAD_CANCEL_DISABLE,禁止線程被取消。這種情況下,如果一個(gè)線程收到取消請(qǐng)求,則它會(huì)將請(qǐng)求掛起,直到該線程允許被取消。
type參數(shù)也有兩個(gè)可選值:
PTHREAD_CANCEL_ASYNCHRONOUS,線程隨時(shí)都可以被取消。它將使得接收到取消請(qǐng)求的目標(biāo)線程立即采取行動(dòng)。
PTHREAD_CANCEL_DEFERRED,允許目標(biāo)線程推遲行動(dòng),直到它調(diào)用了下面幾個(gè)所謂的取消點(diǎn)函數(shù)中的一個(gè):pthread_join、pthread_testcancel、pthread_cond_wait、pthread_cond_timedwait、sem_wait和sigwait。根據(jù)POSIX標(biāo)準(zhǔn),其他可能阻塞的系統(tǒng)調(diào)用,比如read、wait,也可以成為取消點(diǎn)。不過為了安全起見,最好在可能會(huì)被取消的代碼中調(diào)用pthread_testcancel函數(shù)設(shè)置取消點(diǎn)。
(5)獲取當(dāng)前線程ID函數(shù)
pthread_t?pthread_self?(void);
功能:獲取當(dāng)前調(diào)用線程的線程ID。
返回值:當(dāng)前線程的線程ID標(biāo)識(shí)。
(6)分離釋放線程函數(shù)
int?pthread_detach?(pthread_t thread);
功能:線程資源釋放方式設(shè)置函數(shù)。
形參:thread是要釋放線程的標(biāo)識(shí)符ID。
返回值:若是成功返回0,否則返回錯(cuò)誤的編號(hào)。
其他說明:linux線程執(zhí)行和windows不同,pthread有兩種狀態(tài)joinable狀態(tài)和unjoinable狀態(tài)。一個(gè)線程默認(rèn)的狀態(tài)是joinable,如果線程是joinable狀態(tài),當(dāng)線程函數(shù)自己返回退出時(shí)或pthread_exit時(shí),都不會(huì)釋放線程所占用堆棧和線程描述符(總計(jì)8K多),只有當(dāng)調(diào)用了pthread_join之后這些資源才會(huì)被釋放。若是unjoinable狀態(tài)的線程,這些資源在線程函數(shù)退出時(shí)或pthread_exit時(shí)自動(dòng)會(huì)被釋放。unjoinable屬性可以在pthread_create時(shí)指定,或在線程創(chuàng)建后在線程中pthread_detach自己設(shè)置,如:pthread_detach(pthread_self()),將狀態(tài)改為unjoinable狀態(tài),確保資源的釋放。如果線程狀態(tài)為joinable,需要在之后適時(shí)調(diào)用pthread_join。
(7)比較兩個(gè)線程是否為同一線程
int?pthread_equal?(pthread_t thread1, pthread_t thread2);
功能:判斷兩個(gè)線程ID是否是同一個(gè)。
形參:thread1是要比較的線程的標(biāo)識(shí)符ID1;thread2是要比較的線程的標(biāo)識(shí)符ID2。
返回值:不相等返回0,相等非零。
(8)創(chuàng)建線程私有數(shù)據(jù)
int?pthread_key_create?(pthread_key_t *key, void (*destr_function) (void *));
功能:創(chuàng)建線程私有數(shù)據(jù)TSD,提供線程私有的全局變量。使用同名而不同內(nèi)存地址的線程私有數(shù)據(jù)結(jié)構(gòu)。
形參:Key是線程私有數(shù)據(jù)。
第二個(gè)參數(shù):如果第二個(gè)參數(shù)不為空,在線程退出時(shí)將以key所關(guān)聯(lián)數(shù)據(jù)為參數(shù)調(diào)用其指向的資源釋放函數(shù),以釋放分配的緩沖區(qū)。
其他說明:不論哪個(gè)線程調(diào)用pthread_key_create()函數(shù),所創(chuàng)建的key都是所有線程可訪問的,但各個(gè)線程可根據(jù)自己的需要往key中填入不同的值 相當(dāng)于提供了同名不同值的全局變量,各線程對(duì)自己私有數(shù)據(jù)操作互相不影響。
注銷線程私有數(shù)據(jù)
int?pthread_key_delete?(pthread_key_t *key);
該函數(shù)并不檢查當(dāng)前是否有線程正是用該TSD,也不會(huì)調(diào)用清理函數(shù)(destr_function) 將TSD釋放以供下一次調(diào)用pthread_key_create()使用。
(9)讀寫線程私有數(shù)據(jù)
int?pthread_setspecific?(pthread_key_t key, const void *pointer);?//寫
void?pthread_getspecific?(pthread_key_t key); //讀
函數(shù)pthread_setspecific()將pointer的值(非內(nèi)容)與key相關(guān)聯(lián)。函數(shù)pthread_getspecific()將與key相關(guān)聯(lián)的數(shù)據(jù)讀出來。所有數(shù)據(jù)都設(shè)置為void *,因此可以指向任何類型的數(shù)據(jù)。
線程屬性
(1)初始化線程對(duì)象屬性
int?pthread_attr_init?(pthread_attr_t *attr);
功能:pthread_attr_init實(shí)現(xiàn)時(shí)為屬性對(duì)象分配了動(dòng)態(tài)內(nèi)存空間。
形參:attr是指向一個(gè)線程屬性的指針。
返回值:若是成功返回0,否則返回錯(cuò)誤的編號(hào)。
(2)銷毀線程對(duì)象屬性
int?pthread_attr_destroy?(pthread_attr_t *attr);
功能:經(jīng)pthread_attr_destroy去除初始化之后的pthread_attr_t結(jié)構(gòu)被pthread_create函數(shù)調(diào)用,將會(huì)導(dǎo)致其返回錯(cuò)誤。只有再次初始化后才能繼續(xù)使用。
形參:attr是指向一個(gè)線程屬性的指針。
返回值:若是成功返回0,否則返回錯(cuò)誤的編號(hào)。
(3)獲取線程分離狀態(tài)屬性
int?pthread_attr_getdetachstate?(pthread_attr_t *attr, int *detachstate);
功能:獲取線程分離狀態(tài)屬性;另外,pthread_detach()是分離釋放線程資源函數(shù)
形參:attr是指向一個(gè)線程屬性的指針。
detachstate:保存返回的分離狀態(tài)屬性。
返回值:若是成功返回0,否則返回錯(cuò)誤的編號(hào)。
(4)修改線程分離狀態(tài)屬性
int?pthread_attr_setdetachstate?(pthread_attr_t *attr, int detachstate);
功能:修改線程分離狀態(tài)屬性。
形參:attr是指向一個(gè)線程屬性的指針。
detachstate:其含義是線程的脫離狀態(tài),它有兩個(gè)可選值,分別是PTHREAD_CREATE_JOINABLE(可連接)以及PTHREAD_CREATE_DETACHED(分離)。前者指定線程是可以被回收的,后者使調(diào)用線程脫離與進(jìn)程中其他線程同步。脫離了與其他線程同步的線程成為”脫離線程”。脫離線程在退出時(shí)將自行釋放其占用的系統(tǒng)資源。線程創(chuàng)建時(shí)該屬性的默認(rèn)值是PTHREAD_CREATE_JOINABL。此外,我們可以使用pthread_detach函數(shù)直接將線程設(shè)置為脫離線程。(上述detachstate的含義相同,之后相同含義的參數(shù),都只介紹一次)
返回值:若是成功返回0,否則返回錯(cuò)誤的編號(hào)。
(5)獲取線程的CPU親緣性
int?pthread_attr_getaffinity_np?(pthread_attr_t *attr, size_t cpusetsize, cpu_set_t *cpuset);
功能:獲取線程的CPU親緣屬性。
形參:attr是指向一個(gè)線程屬性的指針。
cpusetsize:指向CPU組的緩沖區(qū)大小。
cpuset:指向CPU組的指針。
返回值:若是成功返回0,否則返回錯(cuò)誤的編號(hào)。
(6)設(shè)置線程的CPU親緣性
int?pthread_attr_setaffinity_np?(pthread_attr_t *attr, size_t cpusetsize, const cpu_set_t *cpuset);
功能:通過指定cupset來設(shè)置線程的CPU親緣性。
形參:attr是指向一個(gè)線程屬性的指針。
cpusetsize:指向CPU組的緩沖區(qū)大小。
cpuset:指向CPU組的指針。
返回值:若是成功返回0,否則返回錯(cuò)誤的編號(hào)。
(7)獲取線程的作用域
int?pthread_attr_getscope?(const pthread_attr_t *attr, int *scope);
功能:指定了作用域也就指定了線程與誰競(jìng)爭(zhēng)資源。
形參:attr是指向一個(gè)線程屬性的指針;scope是返回線程的作用域。
返回值:若是成功返回0,否則返回錯(cuò)誤的編號(hào)。
(8)設(shè)置線程的作用域
int?pthread_attr_setscope?(pthread_attr_t *attr, int scope);
功能:指定了作用域也就指定了線程與誰競(jìng)爭(zhēng)資源
形參:attr是指向一個(gè)線程屬性的指針。
scope:線程間競(jìng)爭(zhēng)CPU的范圍,即線程優(yōu)先級(jí)的有效范圍。POSIX標(biāo)準(zhǔn)定義了該屬性可以取以下兩個(gè)值:PTHREAD_SCOPE_SYSTEM和PTHREAD_SCOPE_PROCESS,前者表示目標(biāo)線程與系統(tǒng)中所有線程一起競(jìng)爭(zhēng)CPU的使用,后者表示目標(biāo)線程僅與其他隸屬于同一進(jìn)程的線程競(jìng)爭(zhēng)CPU的使用。
返回值:若是成功返回0,否則返回錯(cuò)誤的編號(hào)。
(9)獲取線程的棧保護(hù)區(qū)大小
int?pthread_attr_getguardsize?(const pthread_attr_t *attr, size_t *guardsize);
功能:獲取線程的棧保護(hù)區(qū)大小。
形參:attr是指向一個(gè)線程屬性的指針。
guardsize:返回獲取的棧保護(hù)區(qū)大小。
返回值:若是成功返回0,否則返回錯(cuò)誤的編號(hào)。
(10)設(shè)置線程的棧保護(hù)區(qū)大小
int?pthread_attr_setguardsize?(pthread_attr_t *attr, size_t *guardsize);
功能:參數(shù)提供了對(duì)棧指針溢出的保護(hù)。默認(rèn)為系統(tǒng)頁大小。
形參:attr是指向一個(gè)線程屬性的指針。
guardsize:線程的棧保護(hù)區(qū)大小。如果guardsize大于0,則系統(tǒng)創(chuàng)建線程的時(shí)候會(huì)在其堆棧的尾部額外分配guardsize字節(jié)的空間,作為保護(hù)堆棧不被錯(cuò)誤地覆蓋的區(qū)域。如果guardsize等于0,則系統(tǒng)不為新創(chuàng)建的線程設(shè)置堆棧保護(hù)區(qū)。如果使用者通過pthread_attr_setstack()或pthread_attr_setstackaddr()函數(shù)手動(dòng)設(shè)置線程的堆棧,則guardsize屬性將被忽略。
返回值:若是成功返回0,否則返回錯(cuò)誤的編號(hào)。
(11)獲取線程的堆棧信息(棧地址和棧大小)
int?pthread_attr_getstack?(const pthread_attr_t *attr, void **stackaddr, size_t *stacksize);
功能:獲取線程的堆棧地址和大小。
形參:attr是指向一個(gè)線程屬性的指針。
stackaddr:返回獲取的棧地址。
stacksize:返回獲取的棧大小。
返回值:若是成功返回0,否則返回錯(cuò)誤的編號(hào)。
(12)設(shè)置線程的堆棧區(qū)
int?pthread_attr_setstack?(pthread_attr_t *attr, void *stackaddr, size_t stacksize);
功能:設(shè)置堆棧區(qū),將導(dǎo)致pthread_attr_setguardsize失效。
形參:attr是指向一個(gè)線程屬性的指針。
stackaddr:線程的堆棧地址,應(yīng)該是可移植的,對(duì)齊頁邊距的,可以用posix_memalign來進(jìn)行獲取。
stacksize:線程的堆棧大小,應(yīng)該是頁大小的整數(shù)倍。
返回值:若是成功返回0,否則返回錯(cuò)誤的編號(hào)。
(13)獲取線程堆棧地址
int?pthread_attr_getstackaddr?(const pthread_attr_t *attr, void **stackaddr);
功能:一般用pthread_attr_getstack來代替。
形參:attr是指向一個(gè)線程屬性的指針;stackaddr是返回獲取的棧地址。
返回值:若是成功返回0,否則返回錯(cuò)誤的編號(hào)。
(14)設(shè)置線程堆棧地址
int?pthread_attr_setstackaddr?(pthread_attr_t *attr, void *stackaddr);
功能:一般用pthread_attr_setstack來代替。
形參:attr是指向一個(gè)線程屬性的指針;stackaddr是設(shè)置線程堆棧地址。
返回值:若是成功返回0,否則返回錯(cuò)誤的編號(hào)。
(15)獲取線程堆棧大小
int?pthread_attr_getstacksize?(const pthread_attr_t *attr, size_t *stacksize);
功能:獲取線程堆棧大小。
形參:attr是指向一個(gè)線程屬性的指針;stacksize是返回線程的堆棧大小。
返回值:若是成功返回0,否則返回錯(cuò)誤的編號(hào)。
(16)設(shè)置線程堆棧大小
int?pthread_attr_setstacksize?(pthread_attr_t *attr, size_t stacksize);
功能:設(shè)置線程堆棧大小。
形參:attr是指向一個(gè)線程屬性的指針。
stacksize:設(shè)置線程的堆棧大小,stack屬性的合法值包括PTHREAD_STACK_MIN,該線程的用戶棧大小將使用默認(rèn)堆棧大小,為某個(gè)線程所需最小堆棧大小,但對(duì)于所有線程,這個(gè)大小可能無法接受,具體指定的大小,即使用線程的用戶堆棧大小的數(shù)值,必須不小于最小堆棧大小PTHREAD_STACK_MIN。
返回值:若是成功返回0,否則返回錯(cuò)誤的編號(hào)。
(17)獲取線程的調(diào)度策略
int?pthread_attr_getschedpolicy?(const pthread_attr_t *attr, int *policy);
功能:獲取線程的調(diào)度策略。
形參:attr是指向一個(gè)線程屬性的指針;policy是返回線程的調(diào)度策略。
返回值:若是成功返回0,否則返回錯(cuò)誤的編號(hào)。
按照如下方法使用sched_get_priority_max()和sched_get_priority_min(),可以得到優(yōu)先級(jí)的最大值和最小值。?
頭文件:#include <pthread.h> #include <sched.h>
調(diào)用形式:
#include <sched.h>
int?sched_get_priority_max(int?policy);
int?sched_get_priority_min(int?policy);
(18)設(shè)置線程的調(diào)度策略
int?pthread_attr_setschedpolicy?(pthread_attr_t *attr, int policy);
頭文件:#include <pthread.h> #include <sched.h>
功能:設(shè)置線程的調(diào)度策略。
形參:attr是指向一個(gè)線程屬性的指針。
policy:線程的調(diào)度策略,POSIX指定了3種調(diào)度策略屬性:SCHED_FIFO表示先入先出策略,SCHED_RR表示輪轉(zhuǎn)調(diào)度(這兩種調(diào)度方法都具備實(shí)時(shí)調(diào)度功能,但只能用于以超級(jí)用戶身份運(yùn)行的進(jìn)程),SCHED_OTHER是系統(tǒng)默認(rèn)策略,SCHED_OTHER是不支持優(yōu)先級(jí)使用的。SCHED_FIFO和SCHED_RR支持優(yōu)先級(jí)的使用,它們分別為1和99,數(shù)值越大優(yōu)先級(jí)越高。
返回值:若是成功返回0,否則返回錯(cuò)誤的編號(hào)。
(19)獲取線程的調(diào)度參數(shù)
int?pthread_attr_getschedparam?(const pthread_attr_t *attr, struct sched_param *param);
頭文件:#include <pthread.h> #include <sched.h>
功能:獲取線程的調(diào)度參數(shù)。
形參:attr是指向一個(gè)線程屬性的指針;param是返回獲取的調(diào)度參數(shù)。
返回值:若是成功返回0,否則返回錯(cuò)誤的編號(hào)。
(20)設(shè)置線程的調(diào)度參數(shù)
int?pthread_attr_setschedparam?(pthread_attr_t *attr, const struct sched_param *param);
頭文件:#include <pthread.h> #include <sched.h>
功能:設(shè)置線程的調(diào)度參數(shù),用于設(shè)置優(yōu)先級(jí)。
形參:attr是指向一個(gè)線程屬性的指針。
param:要設(shè)置的調(diào)度參數(shù),其類型是sched_param結(jié)構(gòu)體。至少需要定義這個(gè)數(shù)據(jù)成員
struct sched_param
{
? ? int sched_priority;
? ? /*該成員表示線程運(yùn)行優(yōu)先級(jí)*/
};
sched_param可能還有其他的數(shù)據(jù)成員,以及多個(gè)用來返回和設(shè)置最小優(yōu)先級(jí)、最大優(yōu)先級(jí)、調(diào)度器、參數(shù)等的函數(shù)。如果調(diào)度策略是SCHED_FIFO或SCHED_RR,那么要求具有值的唯一成員是sched_priority。
返回值:若是成功返回0,否則返回錯(cuò)誤的編號(hào)。
(21)獲取線程是否繼承調(diào)度屬性
int?pthread_attr_getinheritsched?(const pthread_attr_t *attr, int *inheritsched);
頭文件:#include <pthread.h> #include <sched.h>
功能:獲取線程是否繼承調(diào)度屬性。
形參:attr是指向一個(gè)線程屬性的指針;inheritsched是返回繼承調(diào)度屬性的設(shè)置。
返回值:若是成功返回0,否則返回錯(cuò)誤的編號(hào)。
(22)設(shè)置線程繼承調(diào)度屬性
int?pthread_attr_setinheritsched?(pthread_attr_t *attr, int inheritsched);
頭文件:#include <pthread.h> #include <sched.h>
功能:設(shè)置線程是否繼承調(diào)度屬性。
形參:attr是指向一個(gè)線程屬性的指針。
Inheritsched:設(shè)置線程是否繼承調(diào)用線程的調(diào)度屬性,可能取值如下:
PTHREAD_INHERIT_SCHED表示新線程沿用其創(chuàng)建者的線程調(diào)度參數(shù),這種情況下再設(shè)置新線程的調(diào)度參數(shù)屬性將沒有任何效果。PTHREAD_EXPLICIT_SCHED表示調(diào)用者要明確地指定新線程的調(diào)度參數(shù)。
返回值:若是成功返回0,否則返回錯(cuò)誤的編號(hào)。