Linux 線程信號

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);
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容