Linux信号机制探析--信号的处理

Linux 信号机制是进程间通信(IPC)的一种重要方式,主要用于向进程发送异步通知,使进程可以在特定的事件或条件下作出响应。信号机制本质上是一种软件中断,它可以打断进程的正常执行流,迫使进程去处理特定的事件。

1. 信号的基本概念

信号类型

信号是一种有限的整型值,每个信号都有特定的含义。常见的信号包括:

  • SIGINT: 由键盘中断(Ctrl+C)发送,表示进程应被终止。
  • SIGTERM: 请求终止进程,程序可以捕捉此信号并做相应处理。
  • SIGKILL: 强制终止进程,无法被捕捉、阻塞或忽略。
  • SIGHUP: 当控制终端被关闭时发送,常用于通知守护进程重新读取配置。
  • SIGSEGV: 无效的内存访问(段错误)。
  • SIGSTOP: 停止进程的执行,进程无法忽略此信号。
信号的特点
  • 异步性:信号可以在进程执行任何指令时打断其正常流,进行处理。
  • 异步事件:信号通常用于表示异步事件,如硬件中断或外部条件(如定时器到期、用户输入等)。

2. 信号的处理方式

当进程接收到信号时,操作系统会根据进程对该信号的设置,选择适当的处理方式。处理方式主要有以下几种:

1. 默认处理(Default action)

每个信号都有一个默认的处理动作。例如,SIGKILL 的默认动作是终止进程,SIGSEGV 的默认动作是生成 core dump 文件然后终止进程。可以通过 man 7 signal 查看每个信号的默认处理动作。

2. 忽略信号(Ignoring signals)

进程可以选择忽略某些信号。例如:

signal(SIGTERM, SIG_IGN);  // 忽略 SIGTERM 信号
3. 捕捉信号(Catching signals)

进程可以设置自定义的信号处理函数来捕捉特定的信号。当信号发生时,操作系统会执行这个处理函数,而不是默认动作。例如:

void handler(int signum) {
   
   
    printf("Received signal %d\n", signum);
}

int main() {
   
   
    signal(SIGINT, handler);  // 捕捉 SIGINT 信号
    while (1) {
   
   
        sleep(1);
    }
    return 0;
}

在上面的代码中,handler 是一个自定义的信号处理函数,当用户按下 Ctrl+C 触发 SIGINT 信号时,处理函数会被执行。

4. 阻塞信号(Blocking signals)

在某些情况下,进程可能希望暂时阻塞信号,使其不被处理,直到某个时刻再解除阻塞。可以使用 sigprocmask 函数来阻塞或解除阻塞信号。

sigset_t newmask, oldmask;
sigemptyset(&newmask);
sigaddset(&newmask, SIGINT);

// 阻塞 SIGINT 信号
sigprocmask(SIG_BLOCK, &newmask, &oldmask);

// 解除对 SIGINT 的阻塞
sigprocmask(SIG_SETMASK, &oldmask, NULL);

3. 信号的生命周期

  1. 发送信号:信号可以由操作系统、其他进程或本进程自身发送。常用的发送信号的方式有 kill()raise()alarm() 等。例如:

    kill(pid, SIGTERM);  // 向进程 pid 发送 SIGTERM 信号
    
  2. 信号到达:一旦信号被发送,它会进入目标进程的信号队列。信号在进程的某个点被取出并处理。

  3. 信号处理:处理方式如上所述,取决于进程对该信号的设置。

4. 实现信号处理的注意事项

信号处理程序应尽量简单,因为信号处理函数会打断进程的正常执行。如果信号处理函数执行复杂的操作,可能会引发难以调试的错误。常见的注意事项有:

  • 避免在信号处理程序中调用不可重入的函数:例如,printf() 可能会导致死锁或其他问题,因为它在执行过程中可能会被中断。
  • 信号丢失:在 Linux 中,信号不是排队的,某些信号在处理之前可能会被后续信号覆盖。例如,如果在处理某个信号时,新的相同信号到来,旧的信号可能会丢失。因此,对于高频率信号,建议使用 sigaction 而不是 signal 来处理。

5. 信号与实时信号

Linux 支持 POSIX 实时信号(Real-Time Signals),其编号从 SIGRTMIN 开始。与标准信号相比,实时信号具有以下特性:

  • 信号排队:实时信号不会丢失,内核会将每个信号排入队列。
  • 信号优先级:编号越大的实时信号优先级越高。

可以使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

完颜振江

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值