LINUX 線程函數大全
線程
建立一個預設的線程
預設的線程的屬性:
l 非綁定
l 未分離
l 一個預設大小的堆棧
l 具有和父線程一樣的優先順序
用 phread_attr_init() 建立一個預設的屬性對象,
用屬性對象建立一個線程 pthread_create(3T)
int p thread_create ( pthread_t *tid, const pthread_attr_t *tattr, void *(*start_routine)(void*), void *arg );
#include<pthread.h>
pthread_attr_t tattr;
pthread_t tid;
extern void *start_routine(void *arg);
void *arg;
int ret;
/*default behavior*/
ret = pthread_create( &tid, NULL, start_routine, arg );
/*init with default attributes*/
ret = pthread_attr_init( &tattr );
/*default behavior specified*/
ret = pthread_create( &tid, &tattr, start_routine, arg );
tattr 中含有初始化線程所需的屬性,值賦為 NULL 即預設。 start_routine 是線程入口函數的起始地址。當 start_routine 返回時,相應的線程就結束了。線程結束時的退出狀態值是 start_routine 函數用 phread_exit() 函數返回的傳回值。當 pthread_create() 函數調用成功時,線程標識符儲存在參數 tid 指標指向中。
傳回值, pthread_create() 成功後返回 0 ,
EAGAIN 超過了某個限制,如 LWPs 過多。
EINVAL tattr 值非法。
建立子線程時,傳給子線程的輸入參數最好是 malloc() 返回的指標(這樣的指標指向進程堆中的儲存空間)或指向全域變數的指標,而不要是指向局部變數的指標。因為當子線程訪問輸入參數時,建立子線程的函數可能已結束,局部變數也就不存在了。
等待線程結束
pthread_join(3T)
int pthread_join( pthread_t tid, void **status );
#include<pthread.h>
pthread_t tid;
int ret;
int status;
/*waiting to join thread “tid” with status*/
ret = pthread_join( tid, &status );
/*waiting to join thread “tid” without status*/
ret = pthread_join( tid, NULL );
pthread_join() 會阻塞調用它的線程,直到參數 tid 指定的線程結束。 tid 指定的線程必須在當前進程中,且必須是非分離的。 status 接收指定線程終止時的返回狀態代碼。
不能有多個線程等待同一個線程終止,否則返回錯誤碼 ESRCH
當 pthread_join() 返回時,終止線程佔用的堆棧等資源已被回收。
傳回值:成功返回 0
ESRCH tid 指定的線程不是一個當前線程中合法且未分離的線程。
EDEADLK tid 指定的是當前線程。
EINVAL tid 非法。
分離一個線程
pthread_detach(3T)
將非分離線程設定為分離線程。
int pthread_detach( pthread_t tid );
#include<pthread.h>
pthread_t tid;
int ret;
ret = pthread_detach( tid );
該函數通知線程庫,當線程終止以後, tid 所指線程的記憶體可以被立即收回。
傳回值:成功返回 0
EINVAL tid 所指線程不是一個合法線程。
ESRCH tid 指定的線程不是一個當前線程中合法且未分離的線程。
為線程資料建立一個鍵
多線程的 c 語言程式具有三種資料:局部變數,全域變數,線程資料( TSD )
TSD 類似於全域變數,但是線程私人的 。
每個 TSD 都有個鍵同他相關聯。
pthread_key_create(3T)
int pthread_key_create( pthread_key_t *key, void (*destructor)(*void) );
#include<pthread.h>
pthread_key_t key;
int ret;
/*key create without destructor*/
ret = pthread_key_create( &key, NULL );
/*key create with destructor*/
ret = pthread_key_destructor( &key, destructor );
該函數成功時,份配的建放在 key 中,必須保證 key 指向的記憶體區有效 。 destructor 用來釋放不再需要的記憶體。
傳回值:成功返回 0
EAGAIN key 名字空間耗盡
ENOMEM 沒有足夠的記憶體空間建立一個新的鍵。
刪除線程資料的鍵
pthread_key_delete(3T)
solaris 線程介面中沒有該函數
int pthread_key_delete ( pthread_key_t key );
#include<pthread.h>
pthread_key_t key;
int ret;
ret = pthread_key_delete( key );
在調用該函數之前,必須釋放和本線程相關聯的資源, pthread_key_delete() 不會引發鍵的解析函數。
傳回值:成功返回 0
EINVAL key 值非法
設定線程資料鍵
pthread_setspecific(3T)
設定和某個線程資料鍵綁定在一起的線程資料 (一般是指標)
函數將指向專有資料的指標value 設定進 由key指示的結構體 中;
int pthread_setspecific ( pthread_key_t key, const void *value );
#include<pthread.h>
pthread_key_t key;
void *value;
int ret;
ret = pthread_setspecific( key, value );
傳回值:成功返回 0
ENOMEM 沒有足夠的虛擬記憶體
EINVAL key 值非法
pthread_setspecific() 不釋放原來綁定在鍵上的記憶體,給一個鍵綁定新的指標時,必須釋放原指標指向的記憶體 ,否則會發生記憶體流失。
擷取線程資料鍵
pthread_getspecific(3T)
擷取綁定線上程資料鍵上的值,並在指定的位置儲存值
返回存放在對應結構體中的專有指標;
int pthread_getspecific( pthread_key_t key, void**value )
#include<pthread.h>
pthread_key_t key;
void *value;
pthread_getspecific( key, &value );
傳回值:不返回錯誤碼
取線程標識符
pthread_self(3T)
取當前線程的標識符
pthread_t pthread_self( void );
#include<pthread.h>
pthread_t tid;
tid = pthread_self();
傳回值:當前線程標識符。
比較線程標識符
pthread_equal(3T)
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 相同返回非零值,否則返回 0 。如果參數非法,傳回值不可預知。
初始化線程
pthread_once(3T)
用來調用初始化函數,只有第一次調用有效。
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 界定了相應的初始化函數是否被調用過。
傳回值:成功返回 0
EINVAL 某個參數為 NULL
出讓當前線程對處理器的控制權
sched_yeild(3R)
把當前線程的優先權讓給有相同或更高優先順序的線程。
int sched_yeild( void );
#include<pthread.h>
int ret;
ret = sched_yeild();
傳回值:成功返回 0
ENOSYS 目前的版本不支援 sched_yield()
設定線程的優先順序
pthread_setschedparam(3T)
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;
/*only supported policy ,other will result in ENOTSUP*/
policy = SCHED_OTHER;
/*scheduling parameters of target thread*/
ret = pthread_setschedparam( tid, policy, ¶m );
傳回值:成功返回 0
EINVAL 屬性值非法
ENOTSUP 屬性值在目前的版本不支援
取線程的優先順序
pthread_getschedparam(3T)
int pthread_getschedparam( pthread_t tid, int policy, struct schedparam *param );
#include<pthread.h>
pthread_t tid;
sched_param param;
int prioprity;
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;
傳回值:成功返回 0
ESRCH tid 不是一個現存的線程。
向線程發訊號
pthread_kill(3T)
int pthread_kill( pthread_t tid, int sig );
#include<pthread.h>
#include<signal.h>
int sig;
pthread_t tid;
int ret;
ret = pthread_kill( tid, sig );
tid 指定的線程必須和函數當前線程在同一個進程中。
sig 為 0 時,進行錯誤檢查,不發送訊號,往往被用來檢查 tid 的合法性。
傳回值:成功返回 0
EINVAL sig 不是合法訊號量
ESRCH tid 不是當前進程中的線程
訪問當前線程的訊號掩碼
pthread_sigmask(3T)
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 );
ret = pthread_sigmask( SIG_BLOCK, &new, &old );
ret = pthread_sigmask( SIG_UNBLOCK, &new, &old );
how 表示對當前訊號掩碼進行什麼操作。
SIG_SETMASK :在訊號掩碼中加入 new 訊號集, new 表示新增加的要屏蔽的訊號。
SIG_BLOCK :在訊號掩碼中刪去 new 訊號集, new 表示新增加的不需再屏蔽的訊號。
SIG_UNBLOCK :用 new 訊號集替換訊號掩碼, new 表示所有需要屏蔽的訊號。
當 new 為 NULL 時,無論 how 是什麼,當前線程的訊號掩碼都不會改變。
舊的訊號掩碼儲存在 old 中。
傳回值:成功返回 0
EINVAL how 的值未定義
安全的複製
pthread_atfork(3T)
int pthread_atfork( void(*prepare)(void), void(*parent)(void), void(*child)(void) );
終止線程
pthread_exit(3T)
void pthread_exit(void *status);
#include<pthread.h>
int status;
pthread_exit( &status );
終止當前線程,所有綁定線上程鍵上的記憶體將釋放。如果當前線程是未分離的,該線程的標識符和推出代碼( status )被保留,直到其它線程用 pthread_join() 等待當前線程的終止。如果當前線程是分離的, status 被忽略,線程標識符立即收回。
傳回值:若 status 不為 NULL ,線程的結束代碼被置為 status 指向的值。
一個線程可以用一下方式終止自身運行。
從線程的入口函數返回。
調用 pthread_exit()
用 POSIX 的 pthread_cancel()
退出可以用以下方式:
非同步
由線程庫定義的一系列退出點
有應用程式定義的一系列退出點
退出點
由程式通過 pthread_testcancel() 建立
調用了 pthread_cond_wait() 或 pthread_cond_timedwait() 等待一個條件的線程
調用了 pthread_join() 等待另一個線程結束的線程。
被阻塞在 sigwait(2) 上的線程。
一些標準的庫函數。
退出線程
pthread_cancel(3T)
int pthread_cancel( pthread_t thread );
#include<pthread.h>
pthread_t thread;
int ret;
ret = pthread_cancel ( thread ) ;
傳回值:成功返回 0
ESRCH 無指定的線程。
允許或禁止退出
pthread_setcancelstate(3T)
預設是允許退出的。
int pthread_setcancelstate( int state, int *oldstate );
#include<pthread.h>
int oldstate;
int ret;
/*enable*/
ret = pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, &oldstate );
/*disabled*/
ret = pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &oldstate );
傳回值:成功返回 0
EINVAL state 值非法
設定退出類型
pthread_setcanceltype(3T)
可以設定成延遲類型或非同步類型。預設是延遲類型。非同步類型下,線程可以在執行中的任何時候被退出。
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 );
傳回值:成功返回 0
EINVAL state 值非法
建立退出點
pthread_testcancel(3T)
void pthread_testcancel( void );
#include<pthread.h>
pthread_testcancel();
只有當線程的退出狀態是允許退出,退出類型是延遲類型時,有效。
沒有傳回值。
將一個善後處理函數推入退出堆棧
pthread_cleanup_push(3T)
pthread_cleanup_pop(3T)
void Pthread_cleanup_push( void(*routine)(void*), void *args );
void pthread_cleanup_pop( int execute );
#include<pthread.h>
/*push the handler “routine” on cleanup stack*/
pthread_cleanup_push( routine, arg );
/*pop the “func” out of cleanup stack and execute “func”*/
pthread_cleanup_pop( 1 );
/*pop the “func” and don’t execute “func”*/
pthread_cleanup_pop( 0 );
1. 線程屬性
只能線上程建立時制定屬性,不能在運行時改變它。
一旦屬性對象被配置好,它在進程範圍內都是有效。
初始化屬性
pthread_attr_init(3T)
初始化一個線程屬性對象,屬性值是預設值,佔用記憶體由線程庫分配。
int pthread_attr_init( pthread_attr_t *tattr );
#include<pthread.h>
pthread_attr_t tattr;
int ret;
/*initialize an attribute to the default value*/
ret = pthread_attr_init( &tattr );
屬性對象的預設值:
scope (線程域) PTHREAD_SCOPE_PROCESS
Detachstate (分離狀態) PTHREAD_CREATE_JOINABLE
Stackaddr (堆棧地址) NULL
Stacksize (堆棧大小) 1Mb
priority (優先順序) 父進程優先順序
Inheritsched (繼承調度優先順序) PTHREAD_INHERIT_SCHED
schedpolicy (調度策略) SCHED_OTHER
傳回值:成功返回 0
ENOMEM 沒有足夠的記憶體初始化線程屬性對象
釋放屬性對象
pthread_attr_destroy(3T)
int pthread_attr_destroy( pthread_attr_t *tattr );
#include<pthread.h>
pthread_attr_t tattr;
int ret;
ret = pthread_attr_destroy( &tattr );
傳回值:成功返回 0
EINVAL tattr 值非法
設定分離狀態
pthread_attr.setdetachstate(3T)
建立線程時,如果指定這個線程為分離線程,一旦這個線程終止,他的線程標識符和其他相關的資源可以立即被使用。如果不需要等待某個線程終止,可以把它設定為分離。
int pthread_attr_setdetachstate( pthread_attr_t *tattr, int detachstate );
#include<pthread.h>
pthread_attr_t tattr;
int ret;
/*set the thread detach state*/
ret = pthread_attr_setdetachstate( &tattr, PTHREAD_CREATE_DETACHED );
傳回值:成功返回 0
EINVAL tattr 的值或 detachstate 的值非法
取分離狀態
pthread_attr_getdetachstate(3T)
int pthread_attr_getdetachstate( const pthread_attr_t *tattr, int *detachstate );
#include<pthread.h>
pthread_attr_t tattr;
int detachstate;
int ret;
ret = pthread_attr_getdetachstate( &tattr, &detachstate );
傳回值:成功返回 0
EINVAL tattr 的值或 detachstate 的值非法