Solaris
多線程
?
1.
???????
線程
創建一個缺省的線程
缺省的線程的屬性:
l????????
非綁定
l????????
未分離
l????????
一個缺省大小的堆棧
l????????
具有和父線程一樣的優先級
?
用
phread_attr_init()
創建一個缺省的屬性對象,
用屬性對象創建一個線程
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
是線程入口函數的起始地址。當
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)
??????
設置和某個線程數據鍵綁定在一起的線程數據(一般是指針)
??????
?????? 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
的值非法
?
?