1. 線程信號原理
在多線程環(huán)境下,信號處理函數(shù)是多個(gè)線程共有的,若一個(gè)線程修改信號處理函數(shù),則所有的線程均會受到影響。
每個(gè)線程可以有不同的信號屏蔽字,當(dāng)一個(gè)信號發(fā)生時(shí),若該信號與定時(shí)器相關(guān),則信號送給該信號產(chǎn)生的線程中,對于其他信號Linux內(nèi)核隨機(jī)選擇一個(gè)線程進(jìn)行遞送。
當(dāng)多個(gè)線程在調(diào)用sigwait等待同一信號時(shí),只有一個(gè)線程會返回,其他線程繼續(xù)阻塞。
當(dāng)進(jìn)程有針對某一信號有sigaction函數(shù),同時(shí)線程也在等待該信號的發(fā)生,則該信號遞送給線程還是進(jìn)程是不確定的。
2. sigwait的好處
sigwait的功能是等待一些信號的發(fā)生,在調(diào)用該函數(shù)錢需要阻塞sigwait等待的信號,
在調(diào)用sigwait的過程中,線程會解除對寫著信號的阻塞,即信號可以被遞送到線程中。
在進(jìn)程中信號的處理是異步的,信號隨時(shí)有可能發(fā)生,會中斷正在執(zhí)行的指令,需要保證信號處理函數(shù)是可重入的(即信號處理函數(shù)是異步信號安全函數(shù))。
sigwait的好處在于該函數(shù)可以把異步變成同步,主動等待信號的發(fā)生,同步的好處在于不必要求信號處理函數(shù)是異步信號安全的。
3. pthread_sigmask與sigprocmask如何選擇
在多線程環(huán)境中sigprocmask函數(shù)的行為是未定義的,在多線程的環(huán)境中信號屏蔽需要使用pthread_sigmask函數(shù)
4. 檢查一個(gè)線程是否存在
檢查一個(gè)線程是否存在可以調(diào)用pthread_kill函數(shù),該函數(shù)的聲明為:
int pthread_kill(pthread_t thread, int sig);
當(dāng)發(fā)送的信號為0時(shí)可以用來檢查線程是否存在。
下面的代碼用來演示pthread_kill檢查線程是否存在
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
void *func1()/*1秒鐘之后退出*/
{
sleep(1);
printf("線程1(ID:0x%x)退出。/n",(unsigned int)pthread_self());
pthread_exit((void *)0);
}
void *func2()/*5秒鐘之后退出*/
{
sleep(5);
printf("線程2(ID:0x%x)退出。/n",(unsigned int)pthread_self());
pthread_exit((void *)0);
}
void test_pthread(pthread_t tid) /*pthread_kill的返回值:成功(0) 線程不存在(ESRCH) 信號不合法(EINVAL)*/
{
int pthread_kill_err;
pthread_kill_err = pthread_kill(tid,0);
if(pthread_kill_err == ESRCH)
printf("ID為0x%x的線程不存在或者已經(jīng)退出。/n",(unsigned int)tid);
else if(pthread_kill_err == EINVAL)
printf("發(fā)送信號非法。/n");
else
printf("ID為0x%x的線程目前仍然存活。/n",(unsigned int)tid);
}
int main()
{
int ret;
pthread_t tid1,tid2;
pthread_create(&tid1,NULL,func1,NULL);
pthread_create(&tid2,NULL,func2,NULL);
sleep(3);/*創(chuàng)建兩個(gè)進(jìn)程3秒鐘之后,分別測試一下它們是否還活著*/
test_pthread(tid1);/*測試ID為tid1的線程是否存在*/
test_pthread(tid2);/*測試ID為tid2的線程是否存在*/
exit(0);
}