zoukankan      html  css  js  c++  java
  • linux中的信号机制

      

      
    • 概述
      Linux信号机制是在应用软件层次上对中断机制的一种模拟,信号提供了一种处理异步事件的方法,例如,终端用户输入中断键(ctrl+c),则会通过信号机制停止一个程序[1]
      这其实就是向那个程序(进程)发送一个SIGINT信号。每个进程都有一个自己私有的信号处理函数映射表,当该进程成收到一个信号时,对应的信号处理函数被触发执行。而一个进程可以向另外一个进程发送信号,也可以向自己发送信号;操作系统内核也可以向一个进程发送信号,以通知某些硬件事件。信号处理函数映射表中共有64个表项。前32个信号,编号为1 ~ 31,有预定义的含义和处理函数;后32个作为扩充[2]。在终端输入命令“kill -l”就可以看到系统所支持所有的信号。
     
    • 信号机制的两个常用函数

      

        signal

    #include <signal.h>
    void (*signal(int signo, void (*func)(int)))(int);

    返回值:若成功则返回信号以前的处理配置,如果出差则返回SIG_ERR;
    或者用如下的定义:

    typedef void (*sighandler_t)(int);
    sighandler_t signal(int signo, sighandler_t handler);

    这个函数的功能是捕捉到相应的信号(signo),并用相应的处理函数(func/handler)来对信号进行相应的相应,是会替代原来的处理函数。但是要和足以,SIGKILL和SIGSTOP这两个信号是既不能被捕捉也不能被忽略的!(当时我们做一个后台程序,我还想用捕捉SIGKILL的方式来免杀呢)。

      KILL

    #include<signal.h>
    int kill(pid_t pid, int sig);


    这个函数的功能是将信号发送给进程或者进程组。

    pid > 0  :要发送信号的进程号

    pid = 0  :信号被发送到所以和当前进程在同一个进程组的进程

    pid = -1 : 信号发送给发送进程有权限向他们发送信号的系统上的所以进程

    pid < -1 :信号发送给其进程组ID等于pid的绝对值

    • 几个比较常用的信号

    SIGIGN:忽略改信号

    SIGDEF:采用系统默认方式处理信号

    SIGCHLD:在一个进程终止或者停止时,将该信号发送给其父进程,父进程的wait函数通常用来捕捉这个信号

    SIGINT:当用户按中断键(delete/ctrl+c)时将产生这个信号

    SIGKILL:此信号可以用于杀死一个进程

    SIGSTOP:这是个作业控制信号,用于停止一个进程   这个信号和SIGKILL是仅有的两个不能被捕获或忽略的信号

    SYSUSR1/2:用户定义的信号,用于应用程序

    • 程序演示
    /*************************************************************************
        > File Name: signal.c
        > Author: he xingjie
        > Mail: gxmshxj@163.com 
        > Created Time: Fri 25 Oct 2013 07:53:56 AM PDT
     ************************************************************************/
    
    #include<stdio.h>
    #include<stdlib.h>
    #include<signal.h>
    
    void my_func(int sig_no){
        if(sig_no == SIGUSR1)
            printf("Receive SIGUSR1.
    ");
        if(sig_no == SIGUSR2)
            printf("Receive SIGUSR2.
    ");
        if(sig_no == SIGINT)
            printf("Receive SIGINT.
    "); 
    }
    
    int main(void)
    {
        if(signal(SIGUSR1, my_func) == SIG_ERR)
            printf("can't catch SIGUSR1.
    '");
        if(signal(SIGUSR2, my_func) == SIG_ERR)
            printf("can't catch SIGUSR2.
    '");
        if(signal(SIGINT, my_func) == SIG_ERR)
            printf("can't catch SIGINT.
    '");
    
        kill(getpid(),SIGINT);
    
        while(1);
        return 0;
    }

    当运行这个程序的时候,我们将会看到:Receive SIGINT.  然后程序不断在循环,如果我们按ctrl+c,将会输出:Receive SIGINT.

    如果我们把程序放在后天运行,并且用 kill -USR1 pid。pid为那个进程的id,我们还将会看到Receive SIGUSR1.

    • 参考资料

      [1] UNIX环境高级编程

      [2]  我们老师上课的课件

     
  • 相关阅读:
    Python 准确获取今天是星期几的代码(isoweekday和weekday
    python对象之间的交互
    cpu的工作原理
    ubuntu禁止内核自动更新
    计算机组成原理
    python实例化对象过程
    python统计班级学生
    python私有变量和方法
    python变量 方法 属性
    制作再生龙启动盘
  • 原文地址:https://www.cnblogs.com/Jason-Damon/p/3388795.html
Copyright © 2011-2022 走看看