信号通信

信号通信

信号的概念

信号(英文翻译为signal)是Unix系统、类Unix系统(比如Linux系统)以及其他POSIX兼容的操作系统中用于实现进程间通信的一种方式。信号采用的是一种异步通信机制。

  • 同步通信:同步指的是当进程发起一个请求,但是该请求并未马上响应,则进程就会阻塞等待,直到请求被响应。
  • 异步通信:异步指的是当进程发起一个请求,如果该请求并未马上响应,则进程会继续执行其他的任务,过来一段时间请求得到了响应,则会通知该进程,该进程得到通知再去对请求做出处理。

Linux系统中的信号编号为164,**其中编号为131的信号为普通信号,编号为34~64的信号为实时信号。**

  • 普通信号:Linux系统中的普通信号也被称为不可靠信号,指的是当进程接收到了很多的信号请求但是又不能及时处理时,不会把信号形成队列,而是把其余未被处理的信号直接丢弃,只留下一个信号。Linux系统中的普通信号是从Unix系统继承过来的。

  • 实时信号:Linux系统中的实时信号也被称为可靠信号,指的是当进程接收到了很多信号请求但是又不能及时处理时,会把未处理的信号形成队列,然后按照顺序依次处理,不会丢弃信号。Linux系统中的实时信号是新增加的。

信号的产生

  • 按键触发

  • 硬件异常

  • 调用接口

  • 发送指令

  • 内核检测

信号的处理

当进程接收到信号之后,可以分为三种情况来对信号进行处理,分别是默认、捕捉和忽略。

(1) 默认处理

由于Linux系统中已经对普通信号的含义进行了规定,也就是当进程接收到某个信号后,如果用户没有自定义信号的执行动作,则会采用默认处理的方式对信号进行响应。比如进程接收SIGTERM信号后则会被终止。

(2) 捕捉信号

信号捕捉指的是在进程接收到某个指定信号之前,先设计好该信号响应函数,并把该信号和该响应接口进行关联,这样当进程接收到信号之后,就不会执行信号的默认响应动作,而是执行用户指定的响应动作。

(3) 忽略信号

忽略信号指的是当进程接收到某个信号后,并不打算执行该信号的相关动作,而选择直接丢弃该信号。用户可以通过调用signal()函数,只不过函数的第二个参数设置为SIG_IGN即可。

/*********************************************************
*
*   filename:sign
*   function:
*   author  :zzlyx1239.126.com
*   brief   :信号通信
*   date    :2025.4.2
*
*   CopyRight(c) 2025.4.2  zzlyx1239.126.com  AllReserved
***********************************************************/
#include <stdio.h>
#include <signal.h>
void signal_hander(int signum)
{
    switch(signum)
    {
        case SIGUSE1:printf("hello\n");break;
        case SIGUSE2:printf("world\n");break;
    }
}

int main()
{
    signal(SIGUSE1,signal_hander);//用户需要按照该类型定义信号处理接口。
    signal(SIGUSE2,signal_hander);//用户需要按照该类型定义信号处理接口。
    signal(SIGBUS,SIG_DFL);//信号关联默认的响应动作
    signal(SIGINT,SIG_IGN);//指的是信号可以被忽略

    while(1);
    return 0;
}

信号的阻塞

有时进程会接收到很多来自其他进程的信号,但是该进程暂时不打算对某些指定信号做出响应,所以需要暂时“屏蔽”某些信号。比如程序在执行过程中不打算受到用户Ctrl+C的强制结束进程的影响,所以进程需要阻塞该信号,当该信号到达时对它进行屏蔽,当做“看不见”。

Linux系统中提供了一个名称叫做sigprocmask()的函数接口来设置信号集的属性

/*********************************************************
*
*   filename:sign
*   function:
*   author  :zzlyx1239.126.com
*   brief   :信号屏蔽
*   date    :2025.4.2
*
*   CopyRight(c) 2025.4.2  zzlyx1239.126.com  AllReserved
***********************************************************/

#include <stdio.h>
#include <signal.h>

int main()
{
    //1.创建一个信号集
    sigset_t set;
    //2.把需要屏蔽的信号加入该集合中
    sigaddset(&set,SIGINT);
    //3.需要设计该集合的属性
    sigprocmask(SIG_BLOCK,&set,NULL)
    while(1);
    return 0;
}
posted @ 2025-04-03 15:49  骗人就变小狗  阅读(130)  评论(0)    收藏  举报