Solaris 多線程
1.
???????
線程
創(chuàng)建一個(gè)缺省的線程
缺省的線程的屬性:
l???????? 非綁定
l???????? 未分離
l???????? 一個(gè)缺省大小的堆棧
l???????? 具有和父線程一樣的優(yōu)先級(jí)
用 phread_attr_init() 創(chuàng)建一個(gè)缺省的屬性對(duì)象,
用屬性對(duì)象創(chuàng)建一個(gè)線程 pthread_create(3T)
int pthread_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 是線程入口函數(shù)的起始地址。當(dāng) start_routine 返回時(shí),相應(yīng)的線程就結(jié)束了。線程結(jié)束時(shí)的退出狀態(tài)值是 start_routine 函數(shù)用 phread_exit() 函數(shù)返回的返回值。當(dāng) pthread_create() 函數(shù)調(diào)用成功時(shí),線程標(biāo)識(shí)符保存在參數(shù) tid 指針指向中。
返回值, pthread_create() 成功后返回 0 ,
EAGAIN 超過了某個(gè)限制,如 LWPs 過多。
EINVAL?? tattr 值非法。
創(chuàng)建子線程時(shí),傳給子線程的輸入?yún)?shù)最好是
malloc()
返回的指針(這樣的指針指向進(jìn)程堆中的存儲(chǔ)空間)或指向全局變量的指針,而不要是指向局部變量的指針。因?yàn)楫?dāng)子線程訪問輸入?yún)?shù)時(shí),創(chuàng)建子線程的函數(shù)可能已結(jié)束,局部變量也就不存在了。
等待線程結(jié)束
?????? 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() 會(huì)阻塞調(diào)用它的線程,直到參數(shù) tid 指定的線程結(jié)束。 tid 指定的線程必須在當(dāng)前進(jìn)程中,且必須是非分離的。 status 接收指定線程終止時(shí)的返回狀態(tài)碼。
?????? 不能有多個(gè)線程等待同一個(gè)線程終止,否則返回錯(cuò)誤碼 ESRCH
?????? 當(dāng) pthread_join() 返回時(shí),終止線程占用的堆棧等資源已被回收。
?????? 返回值:成功返回 0
?????? ESRCH? tid 指定的線程不是一個(gè)當(dāng)前線程中合法且未分離的線程。
?????? EDEADLK? tid 指定的是當(dāng)前線程。
?????? EINVAL? tid 非法。
分離一個(gè)線程
?????? pthread_detach(3T)
?????? 將非分離線程設(shè)置為分離線程。
??????
?????? int? pthread_detach( pthread_t tid );
?????? #include<pthread.h>
?????? pthread_t? tid;
?????? int? ret;
?????? ret = pthread_detach( tid );
??????
?????? 該函數(shù)通知線程庫,當(dāng)線程終止以后, tid 所指線程的內(nèi)存可以被立即收回。
?????? 返回值:成功返回 0
?????? EINVAL? tid 所指線程不是一個(gè)合法線程。
?????? ESRCH? tid 指定的線程不是一個(gè)當(dāng)前線程中合法且未分離的線程。
為線程數(shù)據(jù)創(chuàng)建一個(gè)鍵
?????? 多線程的 c 語言程序具有三種數(shù)據(jù):局部變量,全局變量,線程數(shù)據(jù)( TSD )
?????? TSD 類似于全局變量,但是線程私有的。
?????? 每個(gè) TSD 都有個(gè)鍵同他相關(guān)聯(lián)。
?????? 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 );
??????
?????? 該函數(shù)成功時(shí),份配的建放在 key 中,必須保證 key 指向的內(nèi)存區(qū)有效。 destructor 用來釋放不再需要的內(nèi)存。
?????? 返回值:成功返回 0
?????? EAGAIN? key 名字空間耗盡
?????? ENOMEM? 沒有足夠的內(nèi)存空間創(chuàng)建一個(gè)新的鍵。
刪除線程數(shù)據(jù)的鍵
?????? pthread_key_delete(3T)
?????? solaris 線程接口中沒有該函數(shù)
??????
?????? int pthread_key_delete( pthread_key_t key );
?????? #include<pthread.h>
?????? pthread_key_t? key;
?????? int? ret;
?????? ret = pthread_key_delete( key );
?????? 在調(diào)用該函數(shù)之前,必須釋放和本線程相關(guān)聯(lián)的資源, pthread_key_delete() 不會(huì)引發(fā)鍵的解析函數(shù)。
?????? 返回值:成功返回 0
?????? EINVAL? key 值非法
設(shè)置線程數(shù)據(jù)鍵
?????? pthread_setspecific(3T)
?????? 設(shè)置和某個(gè)線程數(shù)據(jù)鍵綁定在一起的線程數(shù)據(jù)(一般是指針)
??????
?????? 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? 沒有足夠的虛擬內(nèi)存
?????? EINVAL? key 值非法
?????? pthread_setspecific() 不釋放原來綁定在鍵上的內(nèi)存,給一個(gè)鍵綁定新的指針時(shí),必須釋放原指針指向的內(nèi)存,否則會(huì)發(fā)生內(nèi)存泄漏。
獲取線程數(shù)據(jù)鍵
?????? pthread_getspecific(3T)
?????? 獲取綁定在線程數(shù)據(jù)鍵上的值,并在指定的位置存儲(chǔ)值
??????
?????? int? pthread_getspecific( pthread_key_t key, void**value )
?????? #include<pthread.h>
?????? pthread_key_t? key;
?????? void? *value;
?????? pthread_getspecific( key, &value );
?????? 返回值:不返回錯(cuò)誤碼
取線程標(biāo)識(shí)符
?????? pthread_self(3T)
?????? 取當(dāng)前線程的標(biāo)識(shí)符
??????
?????? pthread_t? pthread_self( void );
?????? #include<pthread.h>
?????? pthread_t? tid;
?????? tid = pthread_self();
?????? 返回值:當(dāng)前線程標(biāo)識(shí)符。
比較線程標(biāo)識(shí)符
?????? 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 。如果參數(shù)非法,返回值不可預(yù)知。
初始化線程
?????? pthread_once(3T)
?????? 用來調(diào)用初始化函數(shù),只有第一次調(diào)用有效。
?????? 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 界定了相應(yīng)的初始化函數(shù)是否被調(diào)用過。
?????? 返回值:成功返回 0
?????? EINVAL? 某個(gè)參數(shù)為 NULL
出讓當(dāng)前線程對(duì)處理器的控制權(quán)
?????? sched_yeild(3R)
?????? 把當(dāng)前線程的優(yōu)先權(quán)讓給有相同或更高優(yōu)先級(jí)的線程。
?????? int? sched_yeild( void );
?????? #include<pthread.h>
?????? int? ret;
?????? ret = sched_yeild();
?????? 返回值:成功返回 0
?????? ENOSYS? 當(dāng)前版本不支持 sched_yield()
設(shè)置線程的優(yōu)先級(jí)
?????? 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? 屬性值在當(dāng)前版本不支持
取線程的優(yōu)先級(jí)
?????? 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 不是一個(gè)現(xiàn)存的線程。
向線程發(fā)信號(hào)
?????? 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 指定的線程必須和函數(shù)當(dāng)前線程在同一個(gè)進(jìn)程中。
?????? sig 為 0 時(shí),進(jìn)行錯(cuò)誤檢查,不發(fā)送信號(hào),往往被用來檢查 tid 的合法性。
?????? 返回值:成功返回 0
?????? EINVAL? sig 不是合法信號(hào)量
?????? ESRCH? tid 不是當(dāng)前進(jìn)程中的線程
訪問當(dāng)前線程的信號(hào)掩碼
?????? 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 表示對(duì)當(dāng)前信號(hào)掩碼進(jìn)行什么操作。
????????????? SIG_SETMASK :在信號(hào)掩碼中加入 new 信號(hào)集, new 表示新增加的要屏蔽的信號(hào)。
????????????? SIG_BLOCK :在信號(hào)掩碼中刪去 new 信號(hào)集, new 表示新增加的不需再屏蔽的信號(hào)。
????????????? SIG_UNBLOCK :用 new 信號(hào)集替換信號(hào)掩碼, new 表示所有需要屏蔽的信號(hào)。
?????? 當(dāng) new 為 NULL 時(shí),無論 how 是什么,當(dāng)前線程的信號(hào)掩碼都不會(huì)改變。
?????? 舊的信號(hào)掩碼保存在 old 中。
?????? 返回值:成功返回 0
?????? EINVAL? how 的值未定義
安全的復(fù)制
?????? 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 );
??????
?????? 終止當(dāng)前線程,所有綁定在線程鍵上的內(nèi)存將釋放。如果當(dāng)前線程是未分離的,該線程的標(biāo)識(shí)符和推出代碼( status )被保留,直到其它線程用 pthread_join() 等待當(dāng)前線程的終止。如果當(dāng)前線程是分離的, status 被忽略,線程標(biāo)識(shí)符立即收回。
?????? 返回值:若 status 不為 NULL ,線程的退出代碼被置為 status 指向的值。
?????? 一個(gè)線程可以用一下方式終止自身運(yùn)行。
?????? 從線程的入口函數(shù)返回。
?????? 調(diào)用 pthread_exit()
?????? 用 POSIX 的 pthread_cancel()
?????? 退出可以用以下方式:
?????? 異步的
?????? 由線程庫定義的一系列退出點(diǎn)
?????? 有應(yīng)用程序定義的一系列退出點(diǎn)
?????? 退出點(diǎn)
?????? 由程序通過 pthread_testcancel() 建立
?????? 調(diào)用了 pthread_cond_wait() 或 pthread_cond_timedwait() 等待一個(gè)條件的線程
?????? 調(diào)用了 pthread_join() 等待另一個(gè)線程結(jié)束的線程。
?????? 被阻塞在 sigwait(2) 上的線程。
?????? 一些標(biāo)準(zhǔn)的庫函數(shù)。
??????
退出線程
?????? 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 值非法
設(shè)置退出類型
?????? pthread_setcanceltype(3T)
?????? 可以設(shè)置成延遲類型或異步類型。缺省是延遲類型。異步類型下,線程可以在執(zhí)行中的任何時(shí)候被退出。
?????? 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 值非法
創(chuàng)建退出點(diǎn)
?????? pthread_testcancel(3T)
?????? void? pthread_testcancel( void );
?????? #include<pthread.h>
?????? pthread_testcancel();
?????? 只有當(dāng)線程的退出狀態(tài)是允許退出,退出類型是延遲類型時(shí),有效。
?????? 沒有返回值。
將一個(gè)善后處理函數(shù)推入退出堆棧
?????? 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.
???????
線程屬性
只能在線程創(chuàng)建時(shí)制定屬性,不能在運(yùn)行時(shí)改變它。
一旦屬性對(duì)象被配置好,它在進(jìn)程范圍內(nèi)都是有效的。
初始化屬性
pthread_attr_init(3T)
?????? 初始化一個(gè)線程屬性對(duì)象,屬性值是缺省值,占用內(nèi)存由線程庫分配。
?????? 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 );
??????
?????? 屬性對(duì)象的缺省值:
?????? scope (線程域) ?????? PTHREAD_SCOPE_PROCESS
?????? Detachstate (分離狀態(tài)) ? PTHREAD_CREATE_JOINABLE
?????? Stackaddr (堆棧地址) ? NULL
?????? Stacksize (堆棧大小) ? 1Mb
?????? priority (優(yōu)先級(jí)) ? 父進(jìn)程優(yōu)先級(jí)
?????? Inheritsched (繼承調(diào)度優(yōu)先級(jí)) ? PTHREAD_INHERIT_SCHED
?????? schedpolicy (調(diào)度策略) ? SCHED_OTHER
??????
?????? 返回值:成功返回 0
?????? ENOMEM? 沒有足夠的內(nèi)存初始化線程屬性對(duì)象
??????
釋放屬性對(duì)象
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 值非法
設(shè)置分離狀態(tài)
pthread_attr.setdetachstate(3T)
?????? 創(chuàng)建線程時(shí),如果指定這個(gè)線程為分離線程,一旦這個(gè)線程終止,他的線程標(biāo)識(shí)符和其他相關(guān)的資源可以立即被使用。如果不需要等待某個(gè)線程終止,可以把它設(shè)定為分離。
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 的值非法
取分離狀態(tài)
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 的值非法
?