1. 程式人生 > >C/C++執行緒的基本函式

C/C++執行緒的基本函式

最近在CSDN上閒逛,不知道看些什麼,刷著刷著就看到了建議性鎖和強制性鎖,看了簡單的概念後又刷到了重入鎖和自旋鎖。發現自己對執行緒裡的鎖瞭解的還不夠深(以前只知道互斥鎖、條件鎖和讀寫鎖),所以現在想先整理下與執行緒相關的函式,然後再學習重入鎖和自旋鎖。

建立執行緒和結束執行緒

(1)執行緒建立函式

int pthread_create (pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

功能:建立一個具有指定引數的執行緒。

形參:thread是要建立的執行緒的執行緒ID指標。

pthread_t型別的定義是typedef unsigned long int pthread_t;(列印時要使用%lu或%u方式)。

attr:建立執行緒時的執行緒屬性(設定NULL表示使用預設執行緒屬性)。

start_routine:指向的是新執行緒將執行的函式。執行緒一旦被建立好,核心就可以排程核心執行緒來執行start_routine函式指標所指向的函數了。

arg:指向的是執行函式的形參。

返回值:若是成功建立執行緒返回0,否則返回錯誤的編號。

(2)等待執行緒結束函式

int pthread_join(pthread_t thread, void **retval);

功能:這個函式是一個執行緒阻塞的函式,呼叫它的函式將一直等待到被等待的執行緒結束為止,當函式返回時,被等待執行緒的資源被收回

形參:thread是被等待的執行緒識別符號。

retval:一個使用者定義的指標,它可以用來儲存被等待執行緒的返回值。

返回值:成功返回0,否則返回錯誤的編號。

錯誤碼:

EDEADLK:可能引起死鎖,比如兩個執行緒互相針對對方呼叫pthread_join,或者執行緒對自身呼叫pthread_join。

EINVAL:目標執行緒是不可回收的,或者已經有其他執行緒在回收目標執行緒。

ESRCH:目標執行緒不存在。

(3)執行緒退出函式

void pthread_exit(void *retval);

功能:執行緒函式在結束時呼叫此函式,以確保安全、乾淨地退出。

形參:retval是函式的返回指標,只要pthread_join中的第二個引數retval不是NULL,這個值將被傳遞給retvalpthread_exit函式通過retval引數向執行緒的回收者傳遞其退出資訊。他執行完之後不會返回到呼叫者,而且永遠不會失敗。

(4)執行緒取消函式

int pthread_cancel(pthread_t thread);

功能:取消某個執行緒的執行。

形參:thread是要取消執行緒的識別符號ID。

返回值:若是成功返回0,否則返回錯誤的編號。

但是,接收到取消請求的目標執行緒可以決定是否允許被取消以及如何取消,這分別由如下兩個函式完成。

int pthread_setcancelstate(int state, int *oldstate);
int pthread_setcanceltype(int type, int *oldtype);

這兩個函式的第一個引數分別用於設定執行緒的取消狀態(是否允許取消)和取消型別(如何取消),第二個引數則分別記錄執行緒原來的取消狀態和取消型別。

state引數有兩個可選值:

PTHREAD_CANCEL_CNABLE,允許執行緒被取消。它是執行緒被建立時的預設取消狀態。

PTHREAD_CANCEL_DISABLE,禁止執行緒被取消。這種情況下,如果一個執行緒收到取消請求,則它會將請求掛起,直到該執行緒允許被取消。

type引數也有兩個可選值:

PTHREAD_CANCEL_ASYNCHRONOUS,執行緒隨時都可以被取消。它將使得接收到取消請求的目標執行緒立即採取行動。

PTHREAD_CANCEL_DEFERRED,允許目標執行緒推遲行動,直到它呼叫了下面幾個所謂的取消點函式中的一個:pthread_join、pthread_testcancel、pthread_cond_wait、pthread_cond_timedwait、sem_wait和sigwait。根據POSIX標準,其他可能阻塞的系統呼叫,比如read、wait,也可以成為取消點。不過為了安全起見,最好在可能會被取消的程式碼中呼叫pthread_testcancel函式設定取消點。

(5)獲取當前執行緒ID函式

pthread_t pthread_self (void);

功能:獲取當前呼叫執行緒的執行緒ID。

返回值:當前執行緒的執行緒ID標識。

(6)分離釋放執行緒函式

int pthread_detach (pthread_t thread);

功能:執行緒資源釋放方式設定函式。

形參:thread是要釋放執行緒的識別符號ID。

返回值:若是成功返回0,否則返回錯誤的編號。

其他說明:linux執行緒執行和windows不同,pthread有兩種狀態joinable狀態和unjoinable狀態。一個執行緒預設的狀態是joinable,如果執行緒是joinable狀態,當執行緒函式自己返回退出時或pthread_exit時,都不會釋放執行緒所佔用堆疊和執行緒描述符(總計8K多),只有當呼叫了pthread_join之後這些資源才會被釋放。若是unjoinable狀態的執行緒,這些資源線上程函式退出時或pthread_exit時自動會被釋放。unjoinable屬性可以在pthread_create時指定,或線上程建立後線上程中pthread_detach自己設定,如:pthread_detach(pthread_self()),將狀態改為unjoinable狀態,確保資源的釋放。如果執行緒狀態為joinable,需要在之後適時呼叫pthread_join。

(7)比較兩個執行緒是否為同一執行緒

int pthread_equal (pthread_t thread1, pthread_t thread2);

功能:判斷兩個執行緒ID是否是同一個。

形參:thread1是要比較的執行緒的識別符號ID1;thread2是要比較的執行緒的識別符號ID2。

返回值:不相等返回0,相等非零。

(8)建立執行緒私有資料

int pthread_key_create (pthread_key_t *key, void (*destr_function) (void *));

功能:建立執行緒私有資料TSD,提供執行緒私有的全域性變數。使用同名而不同記憶體地址的執行緒私有資料結構。

形參:Key是執行緒私有資料。

第二個引數:如果第二個引數不為空,線上程退出時將以key所關聯資料為引數呼叫其指向的資源釋放函式,以釋放分配的緩衝區。

其他說明:不論哪個執行緒呼叫pthread_key_create()函式,所建立的key都是所有執行緒可訪問的,但各個執行緒可根據自己的需要往key中填入不同的值 相當於提供了同名不同值的全域性變數,各執行緒對自己私有資料操作互相不影響。

登出執行緒私有資料

int pthread_key_delete (pthread_key_t *key);

該函式並不檢查當前是否有執行緒正是用該TSD,也不會呼叫清理函式(destr_function) 將TSD釋放以供下一次呼叫pthread_key_create()使用。

(9)讀寫執行緒私有資料

int pthread_setspecific (pthread_key_t key, const void *pointer); //寫
void pthread_getspecific (pthread_key_t key); //讀

函式pthread_setspecific()將pointer的值(非內容)與key相關聯。函式pthread_getspecific()將與key相關聯的資料讀出來。所有資料都設定為void *,因此可以指向任何型別的資料。

執行緒屬性

(1)初始化執行緒物件屬性

int pthread_attr_init (pthread_attr_t *attr);

功能:pthread_attr_init實現時為屬性物件分配了動態記憶體空間。

形參:attr是指向一個執行緒屬性的指標。

返回值:若是成功返回0,否則返回錯誤的編號。

(2)銷燬執行緒物件屬性

int pthread_attr_destroy (pthread_attr_t *attr);

功能:經pthread_attr_destroy去除初始化之後的pthread_attr_t結構被pthread_create函式呼叫,將會導致其返回錯誤。只有再次初始化後才能繼續使用。

形參:attr是指向一個執行緒屬性的指標。

返回值:若是成功返回0,否則返回錯誤的編號。

(3)獲取執行緒分離狀態屬性

int pthread_attr_getdetachstate (pthread_attr_t *attr, int *detachstate);

功能:獲取執行緒分離狀態屬性;另外,pthread_detach()是分離釋放執行緒資源函式

形參:attr是指向一個執行緒屬性的指標。

detachstate:儲存返回的分離狀態屬性。

返回值:若是成功返回0,否則返回錯誤的編號。

(4)修改執行緒分離狀態屬性

int pthread_attr_setdetachstate (pthread_attr_t *attr, int detachstate);

功能:修改執行緒分離狀態屬性。

形參:attr是指向一個執行緒屬性的指標。

detachstate:其含義是執行緒的脫離狀態,它有兩個可選值,分別是PTHREAD_CREATE_JOINABLE(可連線)以及PTHREAD_CREATE_DETACHED(分離)。前者指定執行緒是可以被回收的,後者使呼叫執行緒脫離與程序中其他執行緒同步。脫離了與其他執行緒同步的執行緒成為”脫離執行緒”。脫離執行緒在退出時將自行釋放其佔用的系統資源。執行緒建立時該屬性的預設值是PTHREAD_CREATE_JOINABL此外,我們可以使用pthread_detach函式直接將執行緒設定為脫離執行緒。(上述detachstate的含義相同,之後相同含義的引數,都只介紹一次)

返回值:若是成功返回0,否則返回錯誤的編號。

(5)獲取執行緒的CPU親緣性

int pthread_attr_getaffinity_np (pthread_attr_t *attr, size_t cpusetsize, cpu_set_t *cpuset);

功能:獲取執行緒的CPU親緣屬性。

形參:attr是指向一個執行緒屬性的指標。

cpusetsize:指向CPU組的緩衝區大小。

cpuset:指向CPU組的指標。

返回值:若是成功返回0,否則返回錯誤的編號。

(6)設定執行緒的CPU親緣性

int pthread_attr_setaffinity_np (pthread_attr_t *attr, size_t cpusetsize, const cpu_set_t *cpuset);

功能:通過指定cupset來設定執行緒的CPU親緣性。

形參:attr是指向一個執行緒屬性的指標。

cpusetsize:指向CPU組的緩衝區大小。

cpuset:指向CPU組的指標。

返回值:若是成功返回0,否則返回錯誤的編號。

(7)獲取執行緒的作用域

int pthread_attr_getscope (const pthread_attr_t *attr, int *scope);

功能:指定了作用域也就指定了執行緒與誰競爭資源。

形參:attr是指向一個執行緒屬性的指標;scope是返回執行緒的作用域。

返回值:若是成功返回0,否則返回錯誤的編號。

(8)設定執行緒的作用域

int pthread_attr_setscope (pthread_attr_t *attr, int scope);

功能:指定了作用域也就指定了執行緒與誰競爭資源

形參:attr是指向一個執行緒屬性的指標。

scope:執行緒間競爭CPU的範圍,即執行緒優先順序的有效範圍。POSIX標準定義了該屬性可以取以下兩個值:PTHREAD_SCOPE_SYSTEMPTHREAD_SCOPE_PROCESS前者表示目標執行緒與系統中所有執行緒一起競爭CPU的使用,後者表示目標執行緒僅與其他隸屬於同一程序的執行緒競爭CPU的使用。

返回值:若是成功返回0,否則返回錯誤的編號。

(9)獲取執行緒的棧保護區大小

int pthread_attr_getguardsize (const pthread_attr_t *attr, size_t *guardsize);

功能:獲取執行緒的棧保護區大小。

形參:attr是指向一個執行緒屬性的指標。

guardsize:返回獲取的棧保護區大小。

返回值:若是成功返回0,否則返回錯誤的編號。

(10)設定執行緒的棧保護區大小

int pthread_attr_setguardsize (pthread_attr_t *attr, size_t *guardsize);

功能:引數提供了對棧指標溢位的保護。預設為系統頁大小。

形參:attr是指向一個執行緒屬性的指標。

guardsize:執行緒的棧保護區大小。如果guardsize大於0,則系統建立執行緒的時候會在其堆疊的尾部額外分配guardsize位元組的空間,作為保護堆疊不被錯誤地覆蓋的區域。如果guardsize等於0,則系統不為新建立的執行緒設定堆疊保護區。如果使用者通過pthread_attr_setstack()或pthread_attr_setstackaddr()函式手動設定執行緒的堆疊,則guardsize屬性將被忽略。

返回值:若是成功返回0,否則返回錯誤的編號。

(11)獲取執行緒的堆疊資訊(棧地址和棧大小)

int pthread_attr_getstack (const pthread_attr_t *attr, void **stackaddr, size_t *stacksize);

功能:獲取執行緒的堆疊地址和大小。

形參:attr是指向一個執行緒屬性的指標。

stackaddr:返回獲取的棧地址。

stacksize:返回獲取的棧大小。

返回值:若是成功返回0,否則返回錯誤的編號。

(12)設定執行緒的堆疊區

int pthread_attr_setstack (pthread_attr_t *attr, void *stackaddr, size_t stacksize);

功能:設定堆疊區,將導致pthread_attr_setguardsize失效。

形參:attr是指向一個執行緒屬性的指標。

stackaddr:執行緒的堆疊地址,應該是可移植的,對齊頁邊距的,可以用posix_memalign來進行獲取。

stacksize:執行緒的堆疊大小,應該是頁大小的整數倍。

返回值:若是成功返回0,否則返回錯誤的編號。

(13)獲取執行緒堆疊地址

int pthread_attr_getstackaddr (const pthread_attr_t *attr, void **stackaddr);

功能:一般用pthread_attr_getstack來代替。

形參:attr是指向一個執行緒屬性的指標;stackaddr是返回獲取的棧地址。

返回值:若是成功返回0,否則返回錯誤的編號。

(14)設定執行緒堆疊地址

int pthread_attr_setstackaddr (pthread_attr_t *attr, void *stackaddr);

功能:一般用pthread_attr_setstack來代替。

形參:attr是指向一個執行緒屬性的指標;stackaddr是設定執行緒堆疊地址。

返回值:若是成功返回0,否則返回錯誤的編號。

(15)獲取執行緒堆疊大小

int pthread_attr_getstacksize (const pthread_attr_t *attr, size_t *stacksize);

功能:獲取執行緒堆疊大小。

形參:attr是指向一個執行緒屬性的指標;stacksize是返回執行緒的堆疊大小。

返回值:若是成功返回0,否則返回錯誤的編號。

(16)設定執行緒堆疊大小

int pthread_attr_setstacksize (pthread_attr_t *attr, size_t stacksize);

功能:設定執行緒堆疊大小。

形參:attr是指向一個執行緒屬性的指標。

stacksize:設定執行緒的堆疊大小,stack屬性的合法值包括PTHREAD_STACK_MIN,該執行緒的使用者棧大小將使用預設堆疊大小,為某個執行緒所需最小堆疊大小,但對於所有執行緒,這個大小可能無法接受,具體指定的大小,即使用執行緒的使用者堆疊大小的數值,必須不小於最小堆疊大小PTHREAD_STACK_MIN。

返回值:若是成功返回0,否則返回錯誤的編號。

(17)獲取執行緒的排程策略

int pthread_attr_getschedpolicy (const pthread_attr_t *attr, int *policy);

功能:獲取執行緒的排程策略。

形參:attr是指向一個執行緒屬性的指標;policy是返回執行緒的排程策略。

返回值:若是成功返回0,否則返回錯誤的編號。

按照如下方法使用sched_get_priority_max()和sched_get_priority_min(),可以得到優先順序的最大值和最小值。  標頭檔案:#include <pthread.h> #include <sched.h>

呼叫形式:

#include <sched.h>
int sched_get_priority_max(int policy);
int sched_get_priority_min(int policy);

(18)設定執行緒的排程策略

int pthread_attr_setschedpolicy (pthread_attr_t *attr, int policy);

標頭檔案:#include <pthread.h> #include <sched.h>

功能:設定執行緒的排程策略。

形參:attr是指向一個執行緒屬性的指標。

policy:執行緒的排程策略,POSIX指定了3種排程策略屬性:SCHED_FIFO表示先入先出策略SCHED_RR表示輪轉排程(這兩種排程方法都具備實時排程功能,但只能用於以超級使用者身份執行的程序),SCHED_OTHER是系統預設策略,SCHED_OTHER是不支援優先順序使用的。SCHED_FIFO和SCHED_RR支援優先順序的使用,它們分別為1和99,數值越大優先順序越高。

返回值:若是成功返回0,否則返回錯誤的編號。

(19)獲取執行緒的排程引數

int pthread_attr_getschedparam (const pthread_attr_t *attr, struct sched_param *param);

標頭檔案:#include <pthread.h> #include <sched.h>

功能:獲取執行緒的排程引數。

形參:attr是指向一個執行緒屬性的指標;param是返回獲取的排程引數。

返回值:若是成功返回0,否則返回錯誤的編號。

(20)設定執行緒的排程引數

int pthread_attr_setschedparam (pthread_attr_t *attr, const struct sched_param *param);

標頭檔案:#include <pthread.h> #include <sched.h>

功能:設定執行緒的排程引數,用於設定優先順序。

形參:attr是指向一個執行緒屬性的指標。

param:要設定的排程引數,其型別是sched_param結構體。至少需要定義這個資料成員

struct sched_param
{ 
    int sched_priority; 
    /*該成員表示執行緒執行優先順序*/
};

sched_param可能還有其他的資料成員,以及多個用來返回和設定最小優先順序、最大優先順序、排程器、引數等的函式。如果排程策略是SCHED_FIFO或SCHED_RR,那麼要求具有值的唯一成員是sched_priority。

返回值:若是成功返回0,否則返回錯誤的編號。

(21)獲取執行緒是否繼承排程屬性

int pthread_attr_getinheritsched (const pthread_attr_t *attr, int *inheritsched);

標頭檔案:#include <pthread.h> #include <sched.h>

功能:獲取執行緒是否繼承排程屬性。

形參:attr是指向一個執行緒屬性的指標;inheritsched是返回繼承排程屬性的設定。

返回值:若是成功返回0,否則返回錯誤的編號。

(22)設定執行緒繼承排程屬性

int pthread_attr_setinheritsched (pthread_attr_t *attr, int inheritsched);

標頭檔案:#include <pthread.h> #include <sched.h>

功能:設定執行緒是否繼承排程屬性。

形參:attr是指向一個執行緒屬性的指標。

Inheritsched:設定執行緒是否繼承呼叫執行緒的排程屬性,可能取值如下:

PTHREAD_INHERIT_SCHED表示新執行緒沿用其建立者的執行緒排程引數這種情況下再設定新執行緒的排程引數屬性將沒有任何效果PTHREAD_EXPLICIT_SCHED表示呼叫者要明確地指定新執行緒的排程引數

返回值:若是成功返回0,否則返回錯誤的編號。