POSIX線程庫API(全)(下)編程
請使用 pthread_self(3C) 獲取調用線程的 thread identifier。安全
pthread_t pthread_self(void);
#include <pthread.h> pthread_t tid; tid = pthread_self();
pthread_self() 返回調用線程的 thread identifier。多線程
請使用 pthread_equal(3C) 對兩個線程的線程標識號進行比較。異步
int pthread_equal(pthread_t tid1, pthread_t tid2);
#include <pthread.h> pthread_t tid1, tid2; int ret; ret = pthread_equal(tid1, tid2);
若是 tid1 和 tid2 相等,pthread_equal() 將返回非零值,不然將返回零。若是 tid1 或 tid2 是無效的線程標識號,則結果沒法預測。async
使用 pthread_once(3C),能夠在首次調用 pthread_once 時調用初始化例程。之後調用 pthread_once() 將不起做用。ide
int pthread_once(pthread_once_t *once_control, void (*init_routine)(void));
#include <pthread.h> pthread_once_t once_control = PTHREAD_ONCE_INIT; int ret; ret = pthread_once(&once_control, init_routine);
once_control 參數用來肯定是否已調用相關的初始化例程。函數
pthread_once() 在成功完成以後返回零。其餘任何返回值都表示出現了錯誤。若是出現如下狀況,pthread_once() 將失敗並返回相應的值。spa
EINVAL線程
描述: 接口
once_control 或 init_routine 是 NULL。
使用 sched_yield(3RT),可使當前線程中止執行,以便執行另外一個具備相同或更高優先級的線程。
int sched_yield(void);
#include <sched.h> int ret; ret = sched_yield();
sched_yield() 在成功完成以後返回零。不然,返回 -1,並設置 errno 以指示錯誤狀態。
ENOSYS
描述:
本實現不支持 sched_yield。
請使用 pthread_setschedparam(3C) 修改現有線程的優先級。此函數對於調度策略不起做用。
int pthread_setschedparam(pthread_t tid, int policy, const struct sched_param *param);
#include <pthread.h> pthread_t tid; int ret; struct sched_param param; int priority; /* sched_priority will be the priority of the thread */ sched_param.sched_priority = priority; policy = SCHED_OTHER; /* scheduling parameters of target thread */ ret = pthread_setschedparam(tid, policy, ¶m);
pthread_setschedparam() 在成功完成以後返回零。其餘任何返回值都表示出現了錯誤。若是出現如下任一狀況,pthread_setschedparam() 函數將失敗並返回相應的值。
EINVAL
描述:
所設置屬性的值無效。
ENOTSUP
描述:
嘗試將該屬性設置爲不受支持的值。
pthread_getschedparam(3C) 可用來獲取現有線程的優先級。
int pthread_getschedparam(pthread_t tid, int policy, struct schedparam *param);
#include <pthread.h> pthread_t tid; sched_param param; int priority; int policy; int ret; /* scheduling parameters of target thread */ ret = pthread_getschedparam (tid, &policy, ¶m); /* sched_priority contains the priority of the thread */ priority = param.sched_priority;
pthread_getschedparam() 在成功完成以後返回零。其餘任何返回值都表示出現了錯誤。若是出現如下狀況,該函數將失敗並返回對應的值。
ESRCH
描述:
tid 指定的值不引用現有的線程。
請使用 pthread_kill(3C) 向線程發送信號。
int pthread_kill(thread_t tid, int sig);
#include <pthread.h> #include <signal.h> int sig; pthread_t tid; int ret; ret = pthread_kill(tid, sig);
pthread_kill() 將信號 sig 發送到由 tid 指定的線程。tid 所指定的線程必須與調用線程在同一個進程中。sig 參數必須來自 signal(5) 提供的列表。
若是 sig 爲零,將執行錯誤檢查,但並不實際發送信號。此錯誤檢查可用來檢查 tid 的有效性。
pthread_kill() 在成功完成以後返回零。其餘任何返回值都表示出現了錯誤。若是出現如下任一狀況,pthread_kill() 將失敗並返回相應的值。
EINVAL
描述:
sig 是無效的信號量。
ESRCH
描述:
當前的進程中找不到 tid。
請使用 pthread_sigmask(3C) 更改或檢查調用線程的信號掩碼。
int pthread_sigmask(int how, const sigset_t *new, sigset_t *old);
#include <pthread.h> #include <signal.h> int ret; sigset_t old, new; ret = pthread_sigmask(SIG_SETMASK, &new, &old); /* set new mask */ ret = pthread_sigmask(SIG_BLOCK, &new, &old); /* blocking mask */ ret = pthread_sigmask(SIG_UNBLOCK, &new, &old); /* unblocking */
how 用來肯定如何更改信號組。how 能夠爲如下值之一:
SIG_BLOCK。向當前的信號掩碼中添加 new,其中 new 表示要阻塞的信號組。
SIG_UNBLOCK。從當前的信號掩碼中刪除 new,其中 new 表示要取消阻塞的信號組。
SIG_SETMASK。將當前的信號掩碼替換爲 new,其中 new 表示新的信號掩碼。
當 new 的值爲 NULL 時,how 的值沒有意義,線程的信號掩碼不發生變化。要查詢當前已阻塞的信號,請將 NULL 值賦給 new 參數。
除非 old 變量爲 NULL,不然 old 指向用來存儲之前的信號掩碼的空間。
pthread_sigmask() 在成功完成以後返回零。其餘任何返回值都表示出現了錯誤。若是出現如下狀況,pthread_sigmask() 將失敗並返回相應的值。
EINVAL
描述:
未定義 how 的值。
請參看法決方案: pthread_atfork中有關 pthread_atfork(3C) 的論述。
int pthread_atfork(void (*prepare) (void), void (*parent) (void), void (*child) (void) );
pthread_atfork() 在成功完成以後返回零。其餘任何返回值都表示出現了錯誤。若是出現如下狀況,pthread_atfork() 將失敗並返回相應的值。
ENOMEM
描述:
表空間不足,沒法記錄 Fork 處理程序地址。
請使用 pthread_exit(3C) 終止線程。
void pthread_exit(void *status);
#include <pthread.h> void *status; pthread_exit(status); /* exit with status */
pthread_exit() 函數可用來終止調用線程。將釋放全部線程特定數據綁定。若是調用線程還沒有分離,則線程 ID 和 status 指定的退出狀態將保持不變,直到應用程序調用 pthread_join() 以等待該線程。不然,將忽略 status。線程 ID 能夠當即回收。有關線程分離的信息,請參見設置分離狀態。
調用線程將終止,退出狀態設置爲 status 的內容。
線程可經過如下方法來終止執行:
從線程的第一個(最外面的)過程返回,使線程啓動例程。請參見 pthread_create。
調用 pthread_exit(),提供退出狀態。
使用 POSIX 取消函數執行終止操做。請參見 pthread_cancel()。
線程的缺省行爲是拖延,直到其餘線程經過 "joining" 拖延線程確認其已死亡。此行爲與非分離的缺省 pthread_create() 屬性相同,請參見 pthread_detach。join 的結果是 joining 線程獲得已終止線程的退出狀態,已終止的線程將消失。
有一個重要的特殊狀況,即當初始線程(即調用 main() 的線程)從 main() 調用返回時或調用 exit() 時,整個進程及其全部的線程將終止。所以,必定要確保初始線程不會從 main() 過早地返回。
請注意,若是主線程僅僅調用了 pthread_exit,則僅主線程自己終止。進程及進程內的其餘線程將繼續存在。全部線程都已終止時,進程也將終止。
取消操做容許線程請求終止其所在進程中的任何其餘線程。不但願或不須要對一組相關的線程執行進一步操做時,能夠選擇執行取消操做。
取消線程的一個示例是異步生成取消條件,例如,用戶請求關閉或退出正在運行的應用程序。另外一個示例是完成由許多線程執行的任務。其中的某個線程可能最終完成了該任務,而其餘線程還在繼續運行。因爲正在運行的線程此時沒有任何用處,所以應當取消這些線程。
僅當取消操做安全時才應取消線程。pthreads 標準指定了幾個取消點,其中包括:
經過 pthread_testcancel 調用以編程方式創建線程取消點。
線程等待 pthread_cond_wait 或 pthread_cond_timedwait(3C) 中的特定條件出現。
被 sigwait(2) 阻塞的線程。
一些標準的庫調用。一般,這些調用包括線程可基於其阻塞的函數。有關列表,請參見 cancellation(5) 手冊頁。
缺省狀況下將啓用取消功能。有時,您可能但願應用程序禁用取消功能。若是禁用取消功能,則會致使延遲全部的取消請求,直到再次啓用取消請求。
有關禁用取消功能的信息,請參見pthread_setcancelstate 語法。
執行取消操做存在必定的危險。大多數危險都與徹底恢復不變量和釋放共享資源有關。取消線程時必定要格外當心,不然可能會使互斥保留爲鎖定狀態,從而致使死鎖。或者,已取消的線程可能保留已分配的內存區域,可是系統沒法識別這一部份內存,從而沒法釋放它。
標準 C 庫指定了一個取消接口用於以編程方式容許或禁止取消功能。該庫定義的取消點是一組可能會執行取消操做的點。該庫還容許定義取消處理程序的範圍,以確保這些處理程序在預期的時間和位置運行。取消處理程序提供的清理服務能夠將資源和狀態恢復到與起點一致的狀態。
必須對應用程序有必定的瞭解,才能放置取消點並執行取消處理程序。互斥確定不是取消點,只應當在必要時使之保留儘量短的時間。
請將異步取消區域限制在沒有外部依賴性的序列,由於外部依賴性可能會產生掛起的資源或未解決的狀態條件。在從某個備用的嵌套取消狀態返回時,必定要當心地恢復取消狀態。該接口提供便於進行恢復的功能:pthread_setcancelstate(3C) 在所引用的變量中保留當前的取消狀態,pthread_setcanceltype(3C) 以一樣的方式保留當前的取消類型。
在如下三種不一樣的狀況下可能會執行取消操做:
異步
執行序列中按標準定義的各個點
調用 pthread_testcancel() 時
缺省狀況下,僅在 POSIX 標準可靠定義的點執行取消操做。
不管什麼時候,都應注意資源和狀態恢已復到與起點一致的狀態。
請使用 pthread_cancel(3C) 取消線程。
int pthread_cancel(pthread_t thread);
#include <pthread.h> pthread_t thread; int ret; ret = pthread_cancel(thread);
取消請求的處理方式取決於目標線程的狀態。狀態由如下兩個函數肯定:pthread_setcancelstate(3C) 和 pthread_setcanceltype(3C)。
pthread_cancel() 在成功完成以後返回零。其餘任何返回值都表示出現了錯誤。若是出現如下狀況,該函數將失敗並返回對應的值。
ESRCH
描述:
沒有找到與給定線程 ID 相對應的線程。
請使用 pthread_setcancelstate(3C) 啓用或禁用線程取消功能。建立線程時,缺省狀況下線程取消功能處於啓用狀態。
int pthread_setcancelstate(int state, int *oldstate);
#include <pthread.h> int oldstate; int ret; /* enabled */ ret = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); /* disabled */ ret = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
pthread_setcancelstate() 在成功完成以後返回零。其餘任何返回值都表示出現了錯誤。若是出現如下狀況,pthread_setcancelstate() 函數將失敗並返回相應的值。
EINVAL
描述:
狀態不是 PTHREAD_CANCEL_ENABLE 或 PTHREAD_CANCEL_DISABLE。
使用 pthread_setcanceltype(3C) 能夠將取消類型設置爲延遲或異步模式。
int pthread_setcanceltype(int type, int *oldtype);
#include <pthread.h> int oldtype; int ret; /* deferred mode */ ret = pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype); /* async mode*/ ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
建立線程時,缺省狀況下會將取消類型設置爲延遲模式。在延遲模式下,只能在取消點取消線程。在異步模式下,能夠在執行過程當中的任意一點取消線程。所以建議不使用異步模式。
pthread_setcanceltype() 在成功完成以後返回零。其餘任何返回值都表示出現了錯誤。若是出現如下狀況,該函數將失敗並返回對應的值。
EINVAL
描述:
類型不是 PTHREAD_CANCEL_DEFERRED 或 PTHREAD_CANCEL_ASYNCHRONOUS。
請使用 pthread_testcancel(3C) 爲線程創建取消點。
void pthread_testcancel(void);
#include <pthread.h> pthread_testcancel();
當線程取消功能處於啓用狀態且取消類型設置爲延遲模式時,pthread_testcancel() 函數有效。若是在取消功能處於禁用狀態下調用 pthread_testcancel(),則該函數不起做用。
請務必僅在線程取消操做安全的序列中插入 pthread_testcancel()。除經過 pthread_testcancel() 調用以編程方式創建的取消點之外,pthread 標準還指定了幾個取消點。有關更多詳細信息,請參見取消點。
pthread_testcancel() 沒有返回值。
使用清理處理程序,能夠將狀態恢復到與起點一致的狀態,其中包括清理已分配的資源和恢復不變量。使用 pthread_cleanup_push(3C) 和 pthread_cleanup_pop(3C) 函數能夠管理清理處理程序。
在程序的同一詞法域中能夠推送和彈出清理處理程序。推送和彈出操做應當始終匹配,不然會生成編譯器錯誤。
請使用 pthread_cleanup_push(3C) 將清理處理程序推送到清理棧 (LIFO)。
void pthread_cleanup_push(void(*routine)(void *), void *args);
#include <pthread.h> /* push the handler "routine" on cleanup stack */ pthread_cleanup_push (routine, arg);
pthread_cleanup_push() 沒有返回值。
請使用 pthread_cleanup_pop(3C) 從清理棧中彈出清理處理程序。
void pthread_cleanup_pop(int execute);
#include <pthread.h> /* pop the "func" out of cleanup stack and execute "func" */ pthread_cleanup_pop (1); /* pop the "func" and DONT execute "func" */ pthread_cleanup_pop (0);
若是彈出函數中的參數爲非零值,則會從棧中刪除該處理程序並執行該處理程序。若是該參數爲零,則會彈出該處理程序,而不執行它。
線程顯式或隱式調用 pthread_exit(3C) 時,或線程接受取消請求時,會使用非零參數有效地調用 pthread_cleanup_pop()。
pthread_cleanup_pop() 沒有返回值。