# 守护进程-04-nohup

我们要结束一个进程时可以通过kill命令来实现,kill的过程简单来说是这样:

  1. 使用kill将信号发送到进程的task_struct中,task_struct的特定的成员变量里记下这个信号
  2. 下一次CPU调度到这个进程的时,内核会先执行do\_signal,处理信号

使用kill -l 命令可以查看kill能发送的信号

# nohup

除了利用工具(tmux,screen等),daemon自守护,systemed系统外,我们还可以用nohup来实现进程守护的需求。 使用方式很简单:在要执行的命令前加个nohup即可,如果要后台执行则在末尾加个&。 回到之前的例子:

#include <stdio.h>
main(void)
{
    int d = 1;
    while(1){
        printf("hello %d \n",d);
        fflush(stdout);
        sleep(1);
        d += 1;
    };
    return 0;
}

我们通过nohup来把它运行起来:

root@lan-dev-215:~/test# nohup a.out
nohup: ignoring input and appending output to 'nohup.out'

可以看到有句提示: ignoring input and appending output to 'nohup.out,忽略输入,输出到nohup.out文件。 此时关掉该终端会发现a.out还是在运行。 nohup命令这么简单易用,是怎么实现的呢? 看看nohup.c的源码 https://gist.github.com/kohsuke/0eeb9bb43ca8d62643dd 关键是这两行:

signal (SIGHUP, SIG_IGN);
execvp (*cmd, cmd);

通过signal (SIGHUP, SIG_IGN),把SIGHUP信号忽略,kill 1对它是无效;然后通过execvp (*cmd, cmd) 切换程序背景,nohup把自己变成了a.out,从而实现了我们的守护需求。 来试验下。 先通过nohup 跑起来,然后kill -1一下试试,发现还在运行

root@lan-dev-215:~/test# nohup ./a.out 
nohup: ignoring input and appending output to 'nohup.out'
^C
root@lan-dev-215:~/test# nohup ./a.out &
[1] 27668
root@lan-dev-215:~/test# nohup: ignoring input and appending output to 'nohup.out'

root@lan-dev-215:~/test# kill -1 27668
root@lan-dev-215:~/test# ps aux | grep a.out
root     27668  0.0  0.0   4508   712 pts/1    S    18:21   0:00 ./a.out
root     27674  0.0  0.0  14428  1040 pts/1    S+   18:21   0:00 grep --color=auto a.out

IGNORED位被置为1了

root@lan-dev-215:~/test# ps -C a.out s
  UID   PID          PENDING          BLOCKED          IGNORED           CAUGHT STAT TTY        TIME COMMAND
    0 27668 0000000000000000 0000000000000000 0000000000000001 0000000000000000 S    pts/1      0:00 ./a.out

标准输入0被定向到了/dev/null

root@lan-dev-215:~/test# lsof -p 27668
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
a.out   27668 root  cwd    DIR    8,1     4096 2752642 /root/test
a.out   27668 root  rtd    DIR    8,1     4096       2 /
a.out   27668 root  txt    REG    8,1     8696 2753343 /root/test/a.out
a.out   27668 root  mem    REG    8,1  2030544 5767667 /lib/x86_64-linux-gnu/libc-2.27.so
a.out   27668 root  mem    REG    8,1   170960 5767639 /lib/x86_64-linux-gnu/ld-2.27.so
a.out   27668 root    0w   CHR    1,3      0t0       6 /dev/null
a.out   27668 root    1w   REG    8,1     3328 2753344 /root/test/nohup.out
a.out   27668 root    2w   REG    8,1     3328 2753344 /root/test/nohup.out

感兴趣的话可以去对比下不加nohup时这些的区别。