unix(linux、ubuntu)signal信号的基础理论-----以及KILL命令的实战(基于C语言)

信号是怎么产生的?

1.按键产生:如:Ctrl+c、Ctrl+z、Ctrl+
2.系统调用产生,如:kill、raise、abort
3.软件条件产生,如:定时器信号alarm
4.硬件异常产生,如:非法访问内存(段错误)、除数为0(浮点型例外)、内存对齐出错(总线错误)
5.命令产生,如Kill命令

信号的特点:

简单、不能携带大量信息、特定条件下产生。
如进程1给进程2发送了一个信号,进程2就会暂停目前的操作,转而去处理这个信号,属于一个软中断
信号属于异步事件,进程1给进程2发了一个信号,不用等进程2的响应,可以继续执行其他的操作。

信号的两种状态:

递达:递达并到达进程
未决:产生和递达之间的状态,主要用于阻塞(屏蔽)导致此状态

未决信号集:

1.信号产生,未决信号集中描述该信号的位立刻翻转为1,表明信号处于未决状态,当信号被处理对应位被翻转为0,这一时刻往往非常短暂
2.信号产生后如果有其他原因(一般是阻塞)导致信号不能抵达,在屏蔽解除到达前,未决信号集对应这个时间的位一直是1,处于未决状态

阻塞信号集:

他就是未决信号集前的一堵墙,信号会先辈设置了的堵塞信号集给挡住,这时候未决信号集对应位置给设置成1,什么时候不堵塞,未决信号集才能处理信号,使得对应位翻转成0.

信号的处理方式:

1.执行默认动作
2.忽略(丢弃)
3.捕捉(调用用户自己定义的处理信号函数)

(可在linux终端下使用man 7 signal查看信号执行的默认动作)
//可以看到默认动作有以下五种:Term(终止)、lgn(忽略)、Core(终止并且产生core文件)、Stop(暂停)、Count(继续)这五种默认动作,其中9号(SIGKILL)跟19号(SIGSTOP/SIGCONT)这两信号不能捕捉,不能忽略,甚至不能阻塞

既然KILL命令能产生信号,那我们就先来实战一番KILL命令的实战,实践才能进步
先看KIILL函数的一些小解释:

int  kill(pid_t pid,int sig);
     /*pid大于0,要发送进程ID
     pid=0,代表当前调用系统进程组内所有进程
     pid=-1 代表有权发送所有的进程
     pid<0,代表-pid对应的组内所有进程
     sig对应的信号*/

运行结果如下图:5秒后子进程获取到父进程的pid号,然后杀死了父进程
unix(linux、ubuntu)signal信号的基础理论-----以及KILL命令的实战(基于C语言)_第1张图片

我们通过ps aux 命令查看,可以看到子进程还在运行。
在这里插入图片描述
详细代码如下:

#include<stdio.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>//这两头文件可以通过man 2 kill命令查看,是kill命令所需要的
#include<signal.h>
int main()
{
    int i;
    for(i=0;i<5;i++)
    {
        pid_t pid=fork();
        if(pid==0){
            break;
        }
    }
    if(i==2)
    {
        printf("I will kill father after 5s\n");
        printf("我的pid号是%d\n",getpid());
        sleep(5);
        kill(getppid(),SIGKILL);//获取到父进程的pid并杀死父进程
        while(1){
            sleep(1);
        }
    }
    else if( i==5 )
    {
        while(1){
            printf("I am parent, I am happy\n");
            sleep(1);
        }
    }
    return 0;
}

更深入的实战可以看链接:链接: https://blog.csdn.net/weixin_42569526/article/details/107855647.

你可能感兴趣的:(linux,unix,ubuntu,信号处理,c++)