- 論壇徽章:
- 0
|
Solaris 線程編程 3...........................
進(jìn)程內(nèi)條件變量
#include <thread.h>cond_t cv;int ret;/* to be used within this process only */ret = cond_init(cv, USYNC_THREAD, 0);
進(jìn)程間條件變量
#include <thread.h>cond_t cv;int ret;/* to be used among all processes */ret = cond_init(&cv, USYNC_PROCESS, 0);
cond_init 返回值
cond_init() 在成功運行后返回 0。如果檢測到以下任一情況,cond_init() 將失敗并返回對應(yīng)的值。
EFAULT
描述:
cv 指向的地址非法。
EINVAL
描述:
type 不是可以識別的類型。
銷毀條件變量
使用 cond_destroy(3C) 可以銷毀與 cv 所指向的條件變量相關(guān)聯(lián)的狀態(tài)。用來存儲該條件變量的空間不會釋放。對于 POSIX 線程,請參見pthread_condattr_destroy 語法。
cond_destroy 語法
#include <thread.h>int cond_destroy(cond_t *cv);
cond_destroy 返回值
cond_destroy() 在成功運行后返回 0。如果檢測到以下任一情況,cond_destroy() 將失敗并返回對應(yīng)的值。
EFAULT
描述:
cv 指向的地址非法。
EBUSY
描述:
系統(tǒng)檢測到銷毀活動條件變量的嘗試。
等待條件
使用 cond_wait(3C) 可以原子方式釋放 mp 所指向的互斥鎖,并導(dǎo)致調(diào)用線程基于 cv 所指向的條件變量阻塞。阻塞的線程可以由 cond_signal() 或 cond_broadcast() 喚醒,也可以在信號傳送或 fork() 將其中斷時喚醒。
cond_wait() 每次返回時,互斥鎖均處于鎖定狀態(tài)并由調(diào)用線程擁有,即使返回錯誤時也是如此。
cond_wait 語法
#include <thread.h>int cond_wait(cond_t *cv, mutex_t *mp);
cond_wait 返回值
cond_wait() 在成功運行后返回 0。如果檢測到以下任一情況,cond_wait() 將失敗并返回對應(yīng)的值。
EFAULT
描述:
cv 指向的地址非法。
EBUSY
描述:
等待過程已被信號或 fork() 中斷。
等待絕對時間
cond_timedwait(3C) 與 cond_wait() 非常相似,區(qū)別在于 cond_timedwait() 經(jīng)過 abstime 指定的時間之后不會阻塞。對于 POSIX 線程,請參見pthread_cond_timedwait 語法。
cond_timedwait 語法
#include <thread.h>int cond_timedwait(cond_t *cv, mutex_t *mp, timestruct_t abstime);
cond_timedwait() 每次返回時,互斥鎖均會鎖定并由調(diào)用線程擁有,即使返回錯誤時也是如此。
cond_timedwait() 函數(shù)會一直阻塞,直到該條件獲得信號,或者經(jīng)過最后一個參數(shù)所指定的時間為止。超時以具體的時間指定,這樣即可在不重新計算超時值的情況下高效地重新測試條件。
cond_timedwait 返回值
cond_timedwait() 在成功運行后返回 0。如果檢測到以下任一情況,cond_timedwait() 將失敗并返回對應(yīng)的值。
EFAULT
描述:
cv 指向的地址非法。
ETIME
描述:
由 abstime 指定的時間已過期。
EINVAL
描述:
abstime 無效。
等待時間間隔
cond_reltimedwait(3C) 與 cond_timedwait() 非常相似,區(qū)別在于第三個參數(shù)的值不同。cond_reltimedwait() 的第三個參數(shù)采用相對時間間隔值,而不是絕對時間值。對于 POSIX 線程,請參見 pthread_cond_reltimedwait_np(3C) 手冊頁。
cond_reltimedwait() 每次返回時,互斥鎖均會鎖定并由調(diào)用線程擁有,即使返回錯誤時也是如此。cond_reltimedwait() 函數(shù)一直阻塞,直到該條件獲得信號,或者經(jīng)過最后一個參數(shù)所指定的時間間隔為止。
cond_reltimedwait 語法
#include <thread.h>int cond_reltimedwait(cond_t *cv, mutex_t *mp, timestruct_t reltime);
cond_reltimedwait 返回值
cond_reltimedwait() 在成功運行后返回 0。如果檢測到以下任一情況,cond_reltimedwait() 將失敗并返回對應(yīng)的值。
EFAULT
描述:
cv 指向的地址非法。
ETIME
描述:
由 reltime 指定的時間已過期。
解除阻塞一個線程
對于基于 cv 所指向的條件變量阻塞的線程,使用 cond_signal(3C) 可以解除阻塞該線程。如果沒有線程基于該條件變量阻塞,則調(diào)用 cond_signal() 不起任何作用。
cond_signal 語法
#include <thread.h>int cond_signal(cond_t *cv);
cond_signal 返回值
cond_signal() 在成功運行后返回 0。如果檢測到以下情況,cond_signal() 將失敗并返回對應(yīng)的值。
EFAULT
描述:
cv 指向的地址非法。
解除阻塞所有線程
對于基于 cv 所指向的條件變量阻塞的全部線程,使用 cond_broadcast(3C) 可以解除阻塞這些線程。如果沒有線程基于該條件變量阻塞,則調(diào)用 cond_broadcast() 不起任何作用。
cond_broadcast 語法
#include <thread.h>int cond_broadcast(cond_t *cv);
cond_broadcast 返回值
cond_broadcast() 在成功運行后返回 0。如果檢測到以下情況,cond_broadcast() 將失敗并返回對應(yīng)的值。
EFAULT
描述:
cv 指向的地址非法。
相似的同步函數(shù):信號
信號操作在 Solaris 操作環(huán)境和 POSIX 環(huán)境中均相同。 Solaris 操作環(huán)境中的函數(shù)名 sema_ 在 pthread 中會更改為 sem_。本節(jié)討論了以下主題:
初始化信號
增加信號
基于信號計數(shù)阻塞
減小信號計數(shù)
銷毀信號狀態(tài)
初始化信號
使用 sema_init(3C) 可以通過 count 值來初始化 sp 所指向的信號變量。
sema_init 語法
#include <thread.h>int sema_init(sema_t *sp, unsigned int count, int type, void *arg);
type 可以是以下值之一:
USYNC_PROCESS。信號可用來同步此進(jìn)程和其他進(jìn)程中的線程。信號只能由一個進(jìn)程來初始化。arg 會被忽略。
USYNC_THREAD。信號可用來僅同步此進(jìn)程中的線程。arg 會被忽略。
多個線程決不能同時初始化同一個信號。不得對其他線程正在使用的信號重新初始化。
進(jìn)程內(nèi)信號
#include <thread.h>sema_t sp;int ret;int count;count = 4;/* to be used within this process only */ret = sema_init(&sp, count, USYNC_THREAD, 0);
進(jìn)程間信號
#include <thread.h>sema_t sp;int ret;int count;count = 4;/* to be used among all the processes */ret = sema_init (&sp, count, USYNC_PROCESS, 0);
sema_init 返回值
sema_init() 在成功運行后返回 0。如果檢測到以下任一情況,sema_init() 將失敗并返回對應(yīng)的值。
EINVAL
描述:
sp 引用的信號無效。
EFAULT
描述:
sp 或 arg 指向的地址非法。
增加信號
使用 sema_post(3C) 可以原子方式增加 sp 所指向的信號。如果多個線程基于該信號阻塞,則系統(tǒng)會解除阻塞其中一個線程。
sema_post 語法
#include <thread.h>int sema_post(sema_t *sp);
sema_post 返回值
sema_post() 在成功運行后返回 0。如果檢測到以下任一情況,sema_post() 將失敗并返回對應(yīng)的值。
EINVAL
描述:
sp 引用的信號無效。
EFAULT
描述:
sp 指向的地址非法。
EOVERFLOW
描述:
sp 指向的信號值超過了 SEM_VALUE_MAX。
基于信號計數(shù)阻塞
使用 sema_wait(3C) 可以一直阻塞調(diào)用線程,直到 sp 所指向的信號的計數(shù)變得大于零為止。計數(shù)變得大于零時,系統(tǒng)會以原子方式減小計數(shù)。
sema_wait 語法
#include <thread.h>int sema_wait(sema_t *sp);
sema_wait 返回值
sema_wait() 在成功運行后返回 0。如果檢測到以下任一情況,sema_wait() 將失敗并返回對應(yīng)的值。
EINVAL
描述:
sp 引用的信號無效。
EINTR
描述:
等待過程已被信號或 fork() 中斷。
減小信號計數(shù)
使用 sema_trywait(3C) 可以在計數(shù)大于零時,以原子方式減小 sp 所指向的信號的計數(shù)。此函數(shù)是 sema_wait() 的非阻塞版本。
sema_trywait 語法
#include <thread.h>int sema_trywait(sema_t *sp);
sema_trywait 返回值
sema_trywait() 在成功運行后返回 0。如果檢測到以下任一情況,sema_trywait() 將失敗并返回對應(yīng)的值。
EINVAL
描述:
sp 指向的信號無效。
EBUSY
描述:
sp 所指向的信號的計數(shù)為零。
銷毀信號狀態(tài)
使用 sema_destroy(3C) 可以銷毀與 sp 所指向的信號相關(guān)聯(lián)的任何狀態(tài)。不會釋放用來存儲該信號的空間。
sema_destroy(3C) 語法
#include <thread.h>int sema_destroy(sema_t *sp);
sema_destroy(3C) 返回值
sema_destroy() 在成功運行后返回 0。如果檢測到以下情況,sema_destroy() 將失敗并返回對應(yīng)的值。
EINVAL
描述:
sp 指向的信號無效。
跨進(jìn)程邊界同步
每個同步元語都可以設(shè)置為跨進(jìn)程邊界使用?赏ㄟ^以下方法來設(shè)置跨邊界同步:確保同步變量位于共享內(nèi)存段中,并在 type 設(shè)置為 USYNC_PROCESS 的情況下調(diào)用相應(yīng)的 init 例程。
如果 type 設(shè)置為 USYNC_PROCESS,則針對同步變量執(zhí)行的操作與 type 為 USYNC_THREAD 時針對變量執(zhí)行的操作相同。
mutex_init(&m, USYNC_PROCESS, 0);rwlock_init(&rw, USYNC_PROCESS, 0);cond_init(&cv, USYNC_PROCESS, 0);sema_init(&s, count, USYNC_PROCESS, 0);
生成方和使用者問題示例
示例 8–2 說明了生成方和使用者位于不同進(jìn)程時的生成方和使用者問題。主例程將與其子進(jìn)程共享的全零內(nèi)存段映射到其地址空間。請注意,必須調(diào)用 mutex_init() 和 cond_init(),因為同步變量的 type 為 USYNC_PROCESS。
創(chuàng)建子進(jìn)程是為了運行使用者,父進(jìn)程則運行生成方。
此示例還說明了生成方和使用者的驅(qū)動程序。producer_driver 從 stdin 讀取字符并調(diào)用 producer。consumer_driver 通過調(diào)用 consumer 來獲取字符并將這些字符寫入 stdout 中。
示例 8–2 的數(shù)據(jù)結(jié)構(gòu)與用于解析條件變量的數(shù)據(jù)結(jié)構(gòu)相同。請參見嵌套鎖定和單鏈接列表的結(jié)合使用示例。
--------------------------------------------------------------------------------
示例 8–2 使用 USYNC_PROCESS 時的生成方和使用者問題
- main() { int zfd; buffer_t *buffer; zfd = open(“/dev/zero”, O_RDWR); buffer = (buffer_t *)mmap(NULL, sizeof(buffer_t), PROT_READ|PROT_WRITE, MAP_SHARED, zfd, 0); buffer->occupied = buffer->nextin = buffer->nextout = 0; mutex_init(&buffer->lock, USYNC_PROCESS, 0); cond_init(&buffer->less, USYNC_PROCESS, 0); cond_init(&buffer->more, USYNC_PROCESS, 0); if (fork() == 0) consumer_driver(buffer); else producer_driver(buffer);}void producer_driver(buffer_t *b) { int item; while (1) { item = getchar(); if (item == EOF) { producer(b, `\0'); break; } else producer(b, (char)item); }}void consumer_driver(buffer_t *b) { char item; while (1) { if ((item = consumer(b)) == '\0') break; putchar(item); }}
復(fù)制代碼 --------------------------------------------------------------------------------
創(chuàng)建子進(jìn)程是為了運行使用者,父進(jìn)程則運行生成方。
fork() 和 Solaris 線程的特殊問題
在 Solaris 10 發(fā)行版之前,Solaris 線程和 POSIX 線程以不同的方式定義 fork() 的行為。有關(guān) fork() 問題的詳細(xì)討論,請參見進(jìn)程創(chuàng)建:exec 和 exit 問題。
Solaris libthread 同時支持 fork() 和 fork1()。fork() 調(diào)用具有 "Fork-All" 語義。fork() 可用來復(fù)制進(jìn)程中的所有內(nèi)容(包括線程和 LWP),從而創(chuàng)建父進(jìn)程的準(zhǔn)確克隆。fork1() 調(diào)用所創(chuàng)建的克隆中僅有一個線程,它可復(fù)制進(jìn)程狀態(tài)和地址空間,但是僅克隆調(diào)用線程。
POSIX libpthread 僅支持 fork(),該函數(shù)與 Solaris 線程中的 fork1() 具有相同語義。
fork() 具有 "Fork-All" 語義還是 "Fork-One"語義取決于所使用的庫。使用 -lthread 進(jìn)行鏈接可以賦予 fork() "Fork-All" 語義;使用 -lpthread 進(jìn)行鏈接可以賦予 fork() "Fork-One"語義。
從 Solaris 10 發(fā)行版開始,fork() 在 Solaris 線程和 POSIX 線程中具有相同的語義。具體來說,fork1() 語義僅復(fù)制調(diào)用方。對于需要使用“復(fù)制全部”語義的應(yīng)用程序,提供了一個新函數(shù) forkall()。
EFAULT
描述:
rwlp 指向的地址非法。
相似的 Solaris 線程函數(shù)
表 8–3 相似的 Solaris 線程函數(shù)
操作
相關(guān)函數(shù)說明
創(chuàng)建線程
thr_create 語法
獲取最小的棧大小
thr_min_stack 語法
獲取線程標(biāo)識符
thr_self 語法
停止執(zhí)行線程
thr_yield 語法
向線程發(fā)送信號
thr_kill 語法
訪問調(diào)用線程的信號掩碼
thr_sigsetmask 語法
終止線程
thr_exit 語法
等待線程終止
thr_join 語法
創(chuàng)建線程特定的數(shù)據(jù)鍵
thr_keycreate 語法
設(shè)置線程特定數(shù)據(jù)
thr_setspecific 語法
獲取線程特定數(shù)據(jù)
thr_getspecific 語法
設(shè)置線程優(yōu)先級
thr_setprio 語法
獲取線程優(yōu)先級
thr_getprio 語法
創(chuàng)建線程
thr_create(3C) 例程是 Solaris 線程接口中最詳細(xì)的所有例程其中之一。
使用 thr_create(3C) 可以向當(dāng)前的進(jìn)程中增加新的受控線程。對于 POSIX 線程,請參見pthread_create 語法。
thr_create 語法
#include <thread.h>int thr_create(void *stack_base, size_t stack_size, void *(*start_routine) (void *), void *arg, long flags, thread_t *new_thread);size_t thr_min_stack(void);
請注意,新線程不會繼承暫掛的信號,但確實會繼承優(yōu)先級和信號掩碼。
stack_base。包含新線程所使用的棧的地址。如果 stack_base 為 NULL,則 thr_create() 會為新線程分配一個至少為 stack_size 字節(jié)的棧。
stack_size。包含新線程所使用的棧的大小(以字節(jié)數(shù)表示)。如果 stack_size 為零,則使用缺省大小。在大多數(shù)情況下,零值最適合。如果 stack_size 不為零,則 stack_size 必須大于 thr_min_stack() 返回的值。
通常,無需為線程分配?臻g。系統(tǒng)會為每個線程的沒有保留交換空間的棧分配 1 MB 的虛擬內(nèi)存。系統(tǒng)使用 mmap(2) 的 -MAP_NORESERVE 選項來進(jìn)行分配。
start_routine。包含用以開始執(zhí)行新線程的函數(shù)。start_routine() 返回時,該線程將退出,并且其退出狀態(tài)會設(shè)置為 start_routine 返回的值。請參見thr_exit 語法。
arg。可以是 void 所描述的任何變量,通常是任何大小為 4 字節(jié)的值。對于較大的值,必須通過將該參數(shù)指向?qū)?yīng)的變量來間接傳遞。
請注意,僅可以提供一個參數(shù)。要在程序中采用多個參數(shù),請將多個參數(shù)編碼為單個參數(shù),如通過將這些參數(shù)放在一個結(jié)構(gòu)中。
flags。指定所創(chuàng)建的線程的屬性。在大多數(shù)情況下,最適合使用零值。
flags 中的值是通過對以下參數(shù)執(zhí)行按位或運算(包含邊界值)來構(gòu)造的:
THR_SUSPENDED。暫停新線程,并且不執(zhí)行 start_routine,直到 thr_continue() 啟動該線程為止。使用 THR_SUSPENDED 可以在運行該線程之前對其執(zhí)行操作,如更改其優(yōu)先級。
THR_DETACHED。分離新線程,以便在該線程終止之后,可以立即重用其線程 ID 和其他資源。如果不想等待線程終止,可以設(shè)置 THR_DETACHED。
--------------------------------------------------------------------------------
注 –
如果沒有明確分配同步,則未暫停的分離線程會失敗。如果失敗,則從 thr_create() 返回該線程的創(chuàng)建者之前,會將該線程 ID 重新指定給另一個新線程。
--------------------------------------------------------------------------------
THR_BOUND。將新線程永久綁定到 LWP。新線程是綁定線程。從 Solaris 9 發(fā)行版開始,系統(tǒng)不再區(qū)分綁定線程和非綁定線程,所有的線程均視為綁定線程。
THR_DAEMON。將新線程標(biāo)記為守護(hù)進(jìn)程。守護(hù)進(jìn)程線程始終處于分離狀態(tài)。THR_DAEMON 表示 THR_DETACHED。所有非守護(hù)進(jìn)程線程退出時,該進(jìn)程也會隨之退出。守護(hù)進(jìn)程線程不會影響進(jìn)程的退出狀態(tài),并且在退出對線程數(shù)進(jìn)行計數(shù)時會被忽略。
進(jìn)程的退出方法有兩種,一是調(diào)用 exit(),二是使用進(jìn)程中不是通過 THR_DAEMON 標(biāo)志創(chuàng)建的每個線程來調(diào)用 thr_exit(3C)。 進(jìn)程所調(diào)用的應(yīng)用程序或庫可以創(chuàng)建一個或多個線程,在確定是否退出時應(yīng)當(dāng)忽略(不計數(shù))這些線程。THR_DAEMON 標(biāo)志可標(biāo)識在進(jìn)程退出條件中不計數(shù)的線程。
new_thread。如果 new_thread 不為 NULL,則它將指向 thr_create() 成功時用來存儲新線程 ID 的位置。調(diào)用方負(fù)責(zé)提供該參數(shù)所指向的存儲空間。線程 ID 僅在調(diào)用進(jìn)程中有效。
如果對該標(biāo)識符不感興趣,請向 new_thread 提供一個 NULL 值。
thr_create 返回值
thr_create() 函數(shù)在成功完成之后返回零。其他任何返回值都表示出現(xiàn)了錯誤。如果檢測到以下情況之一,thr_create() 將失敗并返回對應(yīng)的值。
EAGAIN
描述:
超出了系統(tǒng)限制,如創(chuàng)建的 LWP 過多。
ENOMEM
描述:
可用內(nèi)存不足,無法創(chuàng)建新線程。
EINVAL
描述:
stack_base 不為 NULL,并且 stack_size 小于 thr_min_stack() 返回的值。
獲取最小棧大小
使用 thr_min_stack(3C) 可以獲取線程的最小棧大小。
Solaris 線程中的棧行為通常與 pthread 中的棧行為相同。有關(guān)設(shè)置和操作棧的更多信息,請參見關(guān)于棧。
thr_min_stack 語法
#include <thread.h>size_t thr_min_stack(void);
thr_min_stack() 會返回執(zhí)行空線程所需的空間量。創(chuàng)建空線程的目的是執(zhí)行空過程。由于有用線程需要的棧要大于絕對最小棧,因此在減小棧大小時請務(wù)必小心。
執(zhí)行非空過程的線程所分配的棧大小應(yīng)大于 thr_min_stack() 的大小。
如果某個線程是借助于用戶提供的棧創(chuàng)建的,則用戶必須保留足夠的空間才能運行該線程。動態(tài)鏈接的執(zhí)行環(huán)境會增加確定線程最小棧要求的難度。
可以通過兩種方法來指定自定義棧。第一種方法是為棧位置提供 NULL,從而要求運行時庫為該棧分配空間,但是向 thr_create() 提供 stacksize 參數(shù)中所需的大小。
另一種方法是全面負(fù)責(zé)棧管理的各個方面,并向 thr_create() 提供一個指向該棧的指針。這意味著不但需要負(fù)責(zé)分配棧,還需要負(fù)責(zé)取消分配棧。線程終止時,必須安排對該線程的棧進(jìn)行處理。
當(dāng)您分配自己的棧時,請確保通過調(diào)用 mprotect(2) 在該棧末尾附加一個紅色區(qū)域。
大多數(shù)用戶都不應(yīng)當(dāng)通過用戶提供的棧來創(chuàng)建線程。用戶提供的棧之所以存在,只是為了支持要求對其執(zhí)行環(huán)境進(jìn)行完全控制的應(yīng)用程序。
相反,用戶應(yīng)當(dāng)由系統(tǒng)來管理對棧的分配。系統(tǒng)提供的缺省棧應(yīng)當(dāng)能夠滿足所創(chuàng)建的任何線程的要求。
thr_min_stack 返回值
未定義任何錯誤。
獲取線程標(biāo)識符
使用 thr_self(3C) 可以獲取調(diào)用線程的 ID。對于 POSIX 線程,請參見pthread_self 語法。
thr_self 語法
#include <thread.h>thread_t thr_self(void);
thr_self 返回值
未定義任何錯誤。
停止執(zhí)行線程
thr_yield(3C) 會導(dǎo)致當(dāng)前的線程停止執(zhí)行,以便執(zhí)行另一個具有相同或更高優(yōu)先級的線程。 否則,thr_yield() 不起任何作用。但是,調(diào)用 thr_yield() 無法保證當(dāng)前的線程會停止執(zhí)行。
thr_yield 語法
#include <thread.h>void thr_yield(void);
thr_yield 返回值
thr_yield() 不會返回任何內(nèi)容并且不會設(shè)置 errno。
向線程發(fā)送信號
thr_kill(3C) 可用來向線程發(fā)送信號。對于 POSIX 線程,請參見pthread_self 語法。
thr_kill 語法
#include <thread.h>#include <signal.h>int thr_kill(thread_t target_thread, int sig);
thr_kill 返回值
如果成功完成,thr_kill() 將返回 0。如果檢測到以下任一情況,thr_kill() 將失敗并返回對應(yīng)的值。如果失敗,則不發(fā)送任何信號。
ESRCH
描述:
未找到與 thread ID 所指定的線程相關(guān)聯(lián)的線程。
EINVAL
描述:
sig 參數(shù)值不為零。sig 無效或者是不支持的信號編號。
訪問調(diào)用線程的信號掩碼
使用 thr_sigsetmask(3C) 可以更改或檢查調(diào)用線程的信號掩碼。
thr_sigsetmask 語法
#include <thread.h>#include <signal.h>int thr_sigsetmask(int how, const sigset_t *set, sigset_t *oset);
thr_sigsetmask() 可用來更改或檢查調(diào)用線程的信號掩碼。每個線程都有自已的信號掩碼。新線程會繼承調(diào)用線程的信號掩碼和優(yōu)先級,但不會繼承暫掛的信號。新線程的暫掛信號將為空。
如果參數(shù) set 的值不為 NULL,則 set 會指向一組信號,這組信號可用來修改當(dāng)前阻塞的信號組。如果 set 的值為 NULL,則 how 的值沒有意義,并且不會修改線程的信號掩碼。使用此行為可了解有關(guān)當(dāng)前阻塞的信號的情況。
how 的值可指定更改信號組的方法。how 可以為以下值之一。
SIG_BLOCK。set 對應(yīng)于一組要阻塞的信號。這些信號會添加到當(dāng)前的信號掩碼中。
SIG_UNBLOCK。set 對應(yīng)于一組要解除阻塞的信號。這些信號會從當(dāng)前的信號掩碼中刪除。
SIG_SETMASK。set 對應(yīng)于新的信號掩碼。當(dāng)前的信號掩碼將替換為 set。
thr_sigsetmask 返回值
如果成功完成,thr_sigsetmask() 將返回 0。如果檢測到以下任一情況,thr_sigsetmask() 將失敗并返回對應(yīng)的值。
|
|