zoukankan      html  css  js  c++  java
  • linux信号

    信号是由用户、系统、进程发给目标进程的信息,以通知目标进程某个状态的改变或者系统异常。linux信号产生条件为:

    • 在终端输入字符,比如ctrl+z
    • 系统异常
    • 系统状态变化。比如 alarm 定时器到期产生SIGALRM信号
    • 运行kill或者调用kill函数

    查看Linux支持的信号命令:kill -l,可看到如下结果:

     1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP 
    6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1 
    11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM 
    16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP 
    21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ 
    26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR 
    31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3 
    38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8 
    43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 
    48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 
    53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7 
    58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2 
    63) SIGRTMAX-1  64) SIGRTMAX
    

      给一个进程发送信号

    使用 kill 函数:(man 2 kill)

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

      举个栗子:

    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <signal.h>
    #include <errno.h>
    
    int main()
    {
    	pid_t pid = fork();
    
        if (pid > 0)
        {
            printf("in parent program..., child id: %d
    ", pid);
            while (1){}
        }
        else if (pid == 0)
        {
            sleep(2);
            printf("in child program..., cur id: %d
    ", getpid());
            pid_t ppid = getppid();
            printf("befor kill, ppid is %d
    ", ppid);
    
            int ret = kill(ppid, SIGINT);
            printf("kill result is: %d, errno: %d
    ", ret, errno);
            sleep(2);
            ppid = getppid();
            printf("after kill, ppid is %d
    ", ppid);
        }
    
    	return 0;
    }
    

      运行结果为:

    in parent program..., child id: 11519
    in child program..., cur id: 11519
    befor kill, ppid is 11518
    kill result is: 0, errno: 0
    
    sunny@hst:~/program/cpp$ after kill, ppid is 1
    

      在子进程,发送SIGINT(终端终端)信号给父进程,父进程退出。子进程被init进程接管,子进程的父进程号变为1

     

    信号处理

    使用signal函数捕获信号

           #include <signal.h>
    
           typedef void (*sighandler_t)(int);
    
           sighandler_t signal(int signum, sighandler_t handler);
    

      定义sighandler_t类型的函数,该函数接受一个int类型的参数,这个参数指的是信号类型。信号函数应该是可重入的,严禁调用一些不安全的函数。

    SIGKILL和SIGSTOP信号不能被捕获或者忽略。

    除了用户自定义的信号处理函数外,x86_64-linux-gnu/bits/signum-generic.h 文件中,定义了三个其他处理方式:

    #define SIG_ERR  ((__sighandler_t) -1)  /* Error return.  */
    #define SIG_DFL  ((__sighandler_t)  0)  /* Default action.  */
    #define SIG_IGN  ((__sighandler_t)  1)  /* Ignore signal.  */
    

      SIG_IGN 表示忽略信号,SIG_DFL表示使用信号的默认处理方式。

  • 相关阅读:
    创建内核对象的专有命名空间
    内核对象句柄表
    Windows小知识(二)
    内核对象与用户对象/GDI对象
    Windows小知识(一)
    Windows中查看错误
    handle(句柄)
    VC中调用其它程序
    消息映射的转变
    实验6.配置链路聚合
  • 原文地址:https://www.cnblogs.com/zuofaqi/p/9588924.html
Copyright © 2011-2022 走看看