高清宁 发表于 2025-6-11 15:52:54

Linux线程信号的响应

Linux线程信号响应

进程间通信中有种方案是通过信号通信,也就是一个进程可以向其他进程发送信号,如果接收到信号的进程中如果存在多条线程,请问是由哪条线程进行响应?
回答:由于多线程程序中的线程的执行状态是并发的,因此当一个进程收到一个信号时,那么由进程中的哪条线程响应这个信号就是不确定的,取决于哪条线程刚好在信号达到的瞬间被调度,这种不确定性在程序逻辑中一般是不能接收的。
所以可以在接收到信号的进程中指定一条线程对信号进行响应,让进程中的其他线程对该信号进行屏蔽即可。

[*]发送信号给线程
Linux系统中提供了一个名称叫做pthread_kill()的函数接口,用户利用该接口可以向指定的线程发送信号。
如果用户打算给某条线程发送信号的同时还想要发送一个额外的数据,Linux系统提供了一个名称叫做pthread_sigqueue()的函数接口可以实现该功能。
l 线程对信号屏蔽
如果进程中的其他线程不打算对某个信号进行响应,则可以对信号进行屏蔽,Linux系统提供了一个名称叫做sigprocmask()的函数接口可以实现该目的。
另外,Linux系统提供了一个名称叫做pthread_sigmask()的函数,该函数的功能和sigprocmask()一样,只不过是两者的标准不同。
作业:设计一个程序,要求程序中有3条子线程,子线程A接收到SIGINT信号时就输出自身的线程ID,子线程B和子线程C则屏蔽该信号,运行程序并观察效果。
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <signal.h>

sigset_t set;
pthread_t thread;

//信号响应接口
void signal_handler(int signum)
{
        printf("I am taskA,My TID= %d\n",thread);
}


//子线程A调度策略:OTHER
void *task1(void *arg)
{
        thread = pthread_self();
       
        while(1)
        {
               

        }
}

//子线程B调度策略:OTHER
void *task2(void *arg)
{
        sigaddset(&set,SIGINT);
        sigprocmask(SIG_BLOCK,&set,NULL);

        while(1)
        {       
               
       
        }
}

//子线程C调度策略:OTHER
void *task3(void *arg)
{
        sigaddset(&set,SIGINT);
        sigprocmask(SIG_BLOCK,&set,NULL);

        while(1)
        {       
               
       
        }
}

int main(int argc, char const *argv[])
{
        signal(SIGINT,signal_handler);

        //1.创建子线程
        pthread_t thread1;
        pthread_create(&thread1,NULL,task1,NULL);

        //2.创建子线程
        pthread_t thread2;
        pthread_create(&thread2,NULL,task2,NULL);

        //2.创建子线程
        pthread_t thread3;
        pthread_create(&thread3,NULL,task3,NULL);

        pthread_exit(NULL);

        return 0;
}
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: Linux线程信号的响应