linux 信号 kill函数 raise函数 abort函数

信号的概念:

  信号是Linux进程间通信的最古老的方式之一,是事件发生时对进程的通知机制,有时也称之为软件中断,它是在软件层次上对中断机制的一种模拟,是一种异步通信的方式。信号可以导致一个正在运行的进程被另一个正在进行的异步进程中断,转而处理某一个突发事件

  发往进程的诸多信号,通常都是源于内核。引发内核为进程产生信号的各类事件如下:

    - 对于前台进程,用户可以通过输入特殊的终端字符来给它发送信号。比如输入 CTRL+C 通常会给进程发送一个中断信号

    - 硬件发生异常,即硬件检测到一个错误条件并通知内核,随机再由内核发送相应信号给相关进程。比如执行一条异常的机器语言指令,例如被0除,或者引用了无法访问的内存区域。

    - 系统状态变化,比如 alarm 定时器到期将引起 SIGALRM 信号,进程执行的CPU 时间超限,或者该进程的某个子进程退出。

    - 运行 kill 命令 或 调用 kill 函数。

  使用信号的两个目的是:

    - 让进程直到已经发生了一个特定的事情。

    - 强迫进程执行它代码中的信号处理程序。    

  信号的特点:

    - 简单

    - 不能携带大量信息

    - 满足某个特定条件才发送

    - 优先级比较高

  查看系统定义的信号列表: kill -l

  前31个信号为常规信号,其余为实时信号。共62个 32-33:NULL

信号一览表:红色标识事件 + 动作 + 编号 

 信号的5种默认处理动作:

  查看信号的详细信息: man 7 signal

  信号的 5 种默认处理动作

    - Term  终止进程

    - Ign     当前进程忽略掉这个信号

    - Core  终止进程,并生成一个Core文件(Core文件:为了调试程序的错误)

    - Stop  暂停当前进程

    - Cont  继续执行当前被暂停的进程

  信号的几种状态: 产生、未决、递达

  SIGKILL 和 SIGSTOP 信号不能被捕捉、阻塞或者忽略,只能执行默认动作。 

 Core动作:  

  

段错误: Segmentation fault(内核转储)

 修改Core文件大小默认为0 

 终端键入 gcc core.c 生成a.out调试文件 执行a.out文件  如果没有生成 core文件 则可能因为  ubuntu预装了apport错误收集系统,sudo service apport stop之后就可以了     

生成core文件后,进入 gdb调试  之后键入 core-file core(生成core文件) 提示出错误原因和位置 。

信号相关的函数:    

复制代码
 1 /*
 2     #include <signal.h>
 3     int kill(pid_t, int sig);
 4         - 功能:给任何的进程或者进程组 pid,发送任何的信号 sig
 5         - 参数:
 6             - pid:需要发送给的进程的id
 7                 > 0: 将信号发送给指定的进程
 8                 = 0: 将信号发送给当前的进程组
 9                 = -1: 将信号发送给每一个有权限接收这个信号的进程
10                 < -1: 这个pid等于某个进程组的ID取反(-12345表示给12345)
11             - sig: 需要发送的信号的编号或者宏值,0表示不发送任何信号(不同架构编号可能不同,但宏值不变)
12    
13     kill(getppid(),9);//给当前父进程发送信号9
14     kill(getpid(), 9);//给自己发送信号9
15     int raise(int sig);
16         - 功能: 给当前进程发送信号
17         - 参数: 
18             - sig: 要发送的信号
19         - 返回值:
20             - 成功 0
21             - 失败 非0(nonzero)
22         kill(getpid(), sig);
23     void abort(void);
24         - 功能: 发送SIGABRT信号给当前的进程,杀死当前进程
25         kill(getpid(), SIGABRT);
26 */
27 #include <stdio.h>
28 #include <sys/types.h>
29 #include <signal.h>
30 #include <unistd.h>
31 int main()
32 {
33     pid_t pid = fork();
34     if(pid == 0)
35     {
36         //子进程
37         int i = 0;
38         for(i = 0; i < 5; i++)
39         {
40             printf("child process\n");
41             sleep(1);
42         }
43     }
44     else if(pid > 0)
45     {
46         //父进程
47         printf("parent process\n");
48         sleep(2);
49         printf("kill child process now\n");
50         kill(pid,SIGINT);//子进程每隔一秒打印 父进程 每隔两秒杀死子进程 表明子进程只运行两次
51     }
52     return 0;
53 }
复制代码

 

posted on   廿陆  阅读(144)  评论(0编辑  收藏  举报

(评论功能已被禁用)
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示