linux信号

Posted 人生天地之间,若白驹之过隙,忽然而已

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

[email protected]:~/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表示使用信号的默认处理方式。

以上是关于linux信号的主要内容,如果未能解决你的问题,请参考以下文章

[TimLinux] Django 信号

窗函数介绍

linux——信号详解和实操代码

linux——信号详解和实操代码

谷歌地图片段显示,但没有地图

linux打开终端如何启动scala,如何在终端下运行Scala代码片段?