当前位置:首页 » 电脑基础知识

linux 的nohup & 和daemon 总结

2014-03-05 11:10 本站整理 浏览(1210)

linux 的nohup & 和daemon 总结,有需要的朋友可以参考下。


今天和同事聊起了这个问题,就查阅了一下相关资料,总计如下


nohup


nohup 用途:不挂断的运行命令
语法 : nohup command [arg] &

描述: 运行命令,忽略所有SIGHUP信号。 输出到当前目录的nohup.out文件中,如果当前目录不可写,就重定向到$HOME/nohup.out中 一般是要和&配合使用。





&



用户: 将一个程序放到后台执行。 并linux 的nohup &和daemon进程不会和终端分离

后台运行只是终端进行了一次fork,让程序在后台执行,这些都没改变。









daemon





需要两次fork


  1. 屏蔽终端信号:
  2. 在后台运行: 方法就是fork 然后使父进程终止,在子进程中运行
  3. 脱离终端,登录会话和进程组:方式就是调用setsid()使其成为会话组组长

    1. 有必要先介绍一下Linux中的进程与控制终端,登录会话和进程组之间的关系:进程属于一个进程组,进程组号(GID)就是进程组长的进程号(PID)。登录会话可以包含多个进程组。这些进程组共享一个控制终端。这个控制终端通常是创建进程的登录终端。控制终端,登录会话和进程组通常是从父进程继承下来的。我们的目的就是要摆脱它们,使之不受它们的影响。方法是在第2点的基础上,调用setsid()使进程成为会话组长:

  4. 禁止进程重新打开控制终端 :通过再次fork进程,其子进程就不是会话组组长,从而达到禁止其再打开控制终端。


    1. 现在,进程已经成为无终端的会话组长。但它可以重新申请打开一个控制终端。可以通过使进程不再成为会话组长来禁止进程重新打开控制终端:



      if(pid=fork())
      exit(0);//结束第一子进程,第二子进程继续(第二子进程不再是会话组长)



  5. 关闭打开的文件描述符:


    1. 进程从创建它的父进程那里继承了打开的文件描述符。如不关闭,将会浪费系统资源,造成进程所在的文件系统无法卸下以及引起无法预料的错误。按如下方法关闭它们(NOFILE在头文件中定义):



      for(i=0;i < NOFILE;i++)
      close(i);



  6. 改变工作目录:进程活动时,其工作目录所在的文件系统不能卸下。一般需要将工作目录改变到根目录。对于需要转储核心,写运行日志的进程将工作目录改变到特定目录如/tmp:chdir("/tmp")
  7. 重设文件创建掩模:进程从创建它的父进程那里继承了文件创建掩模。它可能修改守护进程所创建的文件的存取位。为防止这一点,将文件创建掩模清除: unmask (0)
  8. 处理SIGCHLD信号:
    理SIGCHLD信号并不是必须的。但对于某些进程,特别是服务器进程往往在请求到来时生成子进程处理请求。如果父进程不等待子进程结束,子进程将成为僵 尸进程(zombie)从而占用系统资源。如果父进程等待子进程结束,将增加父进程的负担,影响服务器进程的并发性能。在Linux下可以简单地将 SIGCHLD信号的操作设为SIG_IGN。
    signal(SIGCHLD,SIG_IGN);








守护进程与用&结尾的后台运行程序有什么区别呢?


最大的区别有几点:


1)守护进程已经完全脱离终端控制台了,而后台程序并未完全脱离终端,在终端未关闭前还是会往终端输出结果


2)守护进程在关闭终端控制台时不会受影响,而后台程序会随用户退出而停止,需要在以nohup xxx & 格式运行才能避免影响


3)守护进程的会话组和当前目录,文件描述符都是独立的。后台运行只是终端进行了一次fork,让程序在后台执行,这些都没改变。





其实有没有必要一定用nohup方式去启动后台进程呢,我觉得没有必要,当一个会话的终端中断后,系统只会给当前会话的前台进程组发送SIGHUP信号,如果启动进程时,让进程在后台去执行,也是执行的时候后面加一个&,也可以自己去重定向输入输出,会话的终端中断时,后台的进程组是不会收到SIGHUP信号,也就不会被系统kill掉,当然也可以在代码里注册SIGHUP该信号,防止进程被kill。(参见http://my.oschina.net/beiyou/blog/76226)



只要是忽略了SIGHUP就可以达到我们需要的终端退出后继续执行的目的那么就是退出ssh后,在我们exit执行的shell时候,会不会向我们后台的jobs发送SIGHUP信号呢?如果发送了SIGHUP信号,那么所有该shell下运行的进程都会被终止,也就是所希望的后台执行没有实现。在shell的options中,有huponexit这个选项,意思就是退出shell时候,是否发送这个SIGHUP信号?



$ shopt
cdable_vars off
cdspell off
checkhash off
checkwinsize off
cmdhist on
dotglob off
execfail off
expand_aliases on
extdebug off
extglob off
extquote on
failglob off
force_fignore on
gnu_errfmt off
histappend off
histreedit off
histverify off
hostcomplete on
huponexit off
interactive_comments on
lithist off
login_shell on
mailwarn off
no_empty_cmd_completion off
nocaseglob off
nocasematch off
nullglob off
progcomp on
promptvars on
restricted_shell off
shift_verbose off
sourcepath on
xpg_echo off



上面的默认选项中,huponexit off,这个情况时候,当你退出shell时候,后台的程序还会继续运行,






http://blog.csdn.net/hepeng597/article/details/9816751