Linux应用编程---12.信号

Linux应用编程—12.信号

​ 信号用于内核层与应用层之间、应用层与应用层之间传递控制指令。在终端下面通过键盘输入“Ctrl + C”就是向操作系统发送了一个控制指令,告诉系统结束当前进程。

​ 在终端下输入“kill -l”即可查看系统支持的所以控制指令。如下图1所示。

image-20221219120233874

图1 查看所有控制指令

​ 如图所示,一共有64个指令。经常使用的“Ctrl + C”就是9号:SIGINT指令,用来结束当前进程。如果父子进程同时运行,在中断下输入“Ctrl + C”只能终止父进程,子进程还在运行。这种情况,我们可以通过控制指令“kill”来结束这个子进程。

​ 查看控制指令“kill”的说明。

NAME
       kill - send a signal to a process

SYNOPSIS
       kill [options] <pid> [...]

DESCRIPTION
       The  default  signal  for kill is TERM.  Use -l or -L to list available
       signals.  Particularly useful signals include  HUP,  INT,  KILL,  STOP,
       CONT,  and  0.   Alternate  signals may be specified in three ways: -9,
       -SIGKILL or -KILL.  Negative PID values may be  used  to  choose  whole
       process  groups; see the PGID column in ps command output.  A PID of -1
       is special; it indicates all processes except the kill  process  itself
       and init.

​ kill指令的作用是发送一个信号到进程。默认情况下这个kill信号是结束进程“TERM”。假如结束进程id号为:7436的进程。在在中断下输入:kill 7436即可。

12.1 signal()函数用来改变信号的处理

​ 函数原型,sighandler_t signal(int signum, sighandler_t handler);其中handler是函数指针,typedef void (*sighandler_t)(int);当触发了某一个信号,会去执行handler入口的函数。原本“SIGINT”的默认功能是结束当前进程,但是如果使用signal()函数重新处理后,当触发到“SIGINT”后,转去执行handler函数,覆盖了以前的功能。设计这样一段程序,使用signal()函数重新改写SIGINT,当键盘输入“Ctrl + C”后,打印字符串“SIGINT triged.”,然后代码每隔1秒钟打印计数值一次。为了方便后续终止这个进程,打印当前进程id号,供终端关闭该进程。

​ 代码如下:

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

void function(int signl);

int main(void)
{
        int i = 0;
        signal(SIGINT, function);

        printf("Process pid = %d\n.", getpid());

        while(1)
        {
                printf("Count to %d.\n", ++i);
                sleep(1);
        }


        return 0;
}


void function(int signl)
{
        printf("SIGINT triged.\n");
}

​ 运行结果:

image-20221219125124360

图2 运行结果

​ 当用户输入“Ctrl + C”时,没有结束当前进程,计数继续,并且打印SIGINT triged.代码运行符合预期。结束当前进程可以通过另一个终端输入:kill 10773.结果如下图3所示:

image-20221219125436427

图3 通过kill指令结束进程

​ 改写代码,使之具有之前的功能——结束当前进程,只需在被触发调用的函数后面加上一个退出即可。exit(1)。修改后代码如下:

void function(int signl)
{
        printf("SIGINT triged.\n");
    	exit(1);
}

​ 运行结果如下:

image-20221219125858271

图4 运行结果

12.2 kill()函数

​ kill()函数是向一个进程发送信号。函数原型如下:int kill(pid_t pid, int sig);入参分别是进程id号pid与信号。返回值,成功:0;失败:-1。

​ 编写一段代码,通过main()函数入参传入进程id号,并且代码中通过调用kill()函数将这个进程终止。

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

int main(int *argc, char *argv[])
{
    kill(atoi(argv[1]), SIGKILL);
    
    return 0;
}

​ 通过gcc编译为KILL 可执行文件,

​ 在终端启动上一个代码,代码正常运行,并且打印进程id号:11099,在另一个终端中执行:./KILL 11099,11099的进程结束。运行结果如下图5所示:

image-20221219132301943

图5 运行结果

12.3 总结

​ 信号用于内核层与应用层、应用层与应用层之间传递控制指令。Linux下有64种信号类型。使用signal()函数可以改写信号的作用,但有的信号不支持。kill()函数可以向一个进程发送某个信号。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值