Signal()函数介绍

一、函数介绍
sig_t signal(int signum, sig_t handler);
signum 此参数指定需要进行设置的信号,可使用信号名(宏)或信号的数字编号,建议使用信号名。
handler sig_t 类型的函数指针,指向信号对应的信号处理函数,当进程接收到信号后会自动执行该处理函数(相当于裸机的中断,中断发生进入中断函数);参数 handler 既可以设置为用户自定义的函数(捕获信号时需要执行的处理函数),也可以设置为 SIG_IGN SIG_DFL SIG_IGN 表示此进程需要忽略该信号, SIG_DFL 则表示设置为系统默认操作
Tips:SIG_IGN、SIG_DFL 分别取值如下:
  • #define SIG_ERR ((sig_t) -1)    /* Error return. */
  • #define SIG_DFL ((sig_t) 0)      /* Default action. */
  • #define SIG_IGN ((sig_t) 1)      /* Ignore signal. */
返回值: 此函数的返回值也是一个 sig_t 类型的函数指针,成功情况下的返回值则是指向在此之前的信号处理函数;如果出错则返回 SIG_ERR ,并会设置 errno
由此可知, signal() 函数可以根据第二个参数 handler 的不同设置情况,可对信号进行不同的处理。
二、测试

代码:

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

static void sig_handler(int sig)
{
    printf("Received signal: %d\n", sig);
}


int main(int argc,char *argv[])
{
    sig_t ret = NULL;
    
    ret = signal(SIGINT,(sig_t)sig_handler);

    if(SIG_ERR == ret)
    {
        perror("signal error");
        exit(-1);
    }

    while(1)
    {
       
    }

    exit(0);
}
在上述示例代码中,我们通过 signal() 函数将 SIGINT 2 )信号绑定到了一个用户自定的处理函数上sig_handler(int sig),当进程收到 SIGINT 信号后会执行该函数然后运行 printf 打印语句。当运行程序之后, 程序会卡在 for 死循环处,此时在终端按下中断符 CTRL + C ,系统便会给前台进程组中的每一个进程发送SIGINT 信号,我们测试程序便会收到该信号。
运行测试:
当运行程序之后,程序会占用终端称为一个前台进程,此时按下中断符便会打印出信息( ^C 表示按下了中断符)。平时大家使用 CTRL + C 可以终止一个进程,而这里却不能通过这种方式来终止这个测试程序,原因在于测试程序中捕获了该信号,而对应的处理方式仅仅只是打印一条语句、而并不终止进程。那此时该怎么关闭这个测试程序呢?前面给大家介绍了“一击必杀”信号 SIGKILL (编号为 9 ),可向该进程发送 SIGKILL 暴力终止该进程,当然一般不推荐大家这样使用,如果实在没办法才采取这种措施。重新打开一个终端,使用 ps 命令找到该进程的 pid 号,再使用 kill 命令,如下所示:

 此时测试程序就会强制终止:

我们再执行一次测试程序,这里将测试程序放在后台运行,然后再按下中断符:

 

按下中断符发现进程并没有收到 SIGINT 信号,原因很简单,因为进程并不是前台进程、而是一个后台 进程,按下中断符时系统并不会给后台进程发送 SIGINT 信号。可以使用 kill 命令手动发送信号给我们的进程:

  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值