进程信号

    xiaoxiao2025-08-03  24

    1.信号简介

    1.用户输入命令,在shell下启动一个进程。 2.按下ctrl+c,这是键盘输入产生一个硬件中断,被os获取,解释成信号,发送给前台进程 3.前台进程收到信号,进而引起进程退出。 ps:信号是进程之间事件异步通知的一种方式,属于软中断

    使用命令 kill -l 可以查看信号

    2.产生信号的四种方式

    键盘按键产生(ctrl + c…)硬件条件产生 硬件异常被硬件以某种方式被硬件检测到并通知内核,然后内核向当前进程发送适当的信号。例如当前进程执行了除以0的指令,CPU的运算单元会产生异常,内核将这个异常解释 为SIGFPE信号发送给进程。再比如当前进程访问了非法内存地址,MMU会产生异常,内核将这个异常解释为SIGSEGV信号发送给进程。软件条件产生系统调用产生(kill)

    3.信号的处理方式

    忽略默认处理行为,终止进程捕捉信号,

    4.信号的捕捉

    捕捉一下2号信号使ctrl+c失效,但是可以使用其他信号中断(ctrl+\)

    #include<signal.h> #include<stdio.h> void hehe(int sig){ printf("signal=%d\n",sig); } int main() { signal(2,hehe); while(1); return 0; }

    ps:我们在C/C++当中除零,内存越界等异常,在系统层面上,是被当成信号处理的

    5.信号捕捉流程

    信号处理函数是一个独立的执行流,和原来的用户代码之间没有相互调用的关系 信号处理函数执行过程中,原有的执行流就在等待

    6.阻塞信号

    有时候信号不会立刻被处理,而是等到何时的时机在进行处理

    实际执行信号的处理动作称为信号递达(Delivery);信号从产生到递达之间的状态,称为信号未决(Pending);进程可以选择阻塞 (Block )某个信号;被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作;注意,阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略是在递达之后可选的一种处理动作;

    7.可重入函数

    一个函数如果在多个执行流中被调用,就可能出现问题‘

    一个函数如果可重入,就意味着在多个执行流中调用是没问题的。

    一个函数如果不可重入,在多个执行流中调用就是有问题的。

    如果一个函数使用了全局变量/静态变量,不可重入

    如果一个函数调用了不可重入函数,也是不可重入的,

    如下创建20次子进程应该结束20次子进程打印20次child exit,可实际没有退出完,出现了僵尸进程,是因为在同时收到多个信号,只执行了一次。

    #include<signal.h> #include<stdio.h> #include<sys/wait.h> #include<unistd.h> #include<stdlib.h> void hehe(int sig) { printf("child exit\n"); wait(NULL); } int main() { //signal(SIGCHLD, SIG_IGN); signal(17,hehe); int i = 0; for(;i<20; ++i){ pid_t ret = fork(); if(ret == 0){ printf("hehehepid %d\n",getpid()); exit(0); } } while(1) { sleep(1); } return 0; }

    //signal(SIGCHLD, SIG_IGN); 捕获信号之后

    最新回复(0)