linux中的前台任务、后台任务和守护进程

时间:2021-08-14 17:25:25

前台任务、后台任务和守护进程

标签:linux


部分内容参考:http://www.ruanyifeng.com/blog/2016/02/linux-daemon.html

  • 前台任务

    • 特点
        ”前台任务”(foreground job)是独占命令行窗口的任务,只有运行完了或者手动中止该任务,才能执行其他命令。
  • 后台任务

    • 简介
        与前台任务相对应,在多任务系统中,有一些任务在运行的时候,并不需要与用户交互。它们通常在不打扰用户其它工作的时候默默地执行(此时可以输入其他的命令)。
    • 特点

      • 继承当前session(对话)的标准输出(stdout)和标准错误(stderr)。因此,后台任务的所有输出依然会同步地在命令行下显示。
      • 不再继承当前session的标准输入(stdin)。你无法向这个任务输入指令了。如果它试图读取标准输入,就会暂停执行(halt)。

        可以看出,”后台任务”与”前台任务”的本质区别只有一个:是否继承标准输入。所以,执行后台任务的同时,用户还可以输入其他命令。

  • 前台任务变为后台任务

    • 启动时变为后台任务
        只要在命令的后面加上 & ,启动的进程就会成为“后台进程”。
    • 将正在运行的“前台任务”变为后台任务
        先 ctrl+z ,之后执行 bg 命令。相当于让最近一个暂停的“后台任务”继续执行。

    CTRL+ZCTRL+C的对比
      CTRL+ZCTRL+C 都是中断命令,但是他们的作用却不一样. CTRL+C 是强制中断程序的执行,而 CTRL+Z 的是将任务中断,但是此任务并没有结束,仍然在进程中,只是维持挂起的状态,用户可以使用 fg/bg 操作继续前台或后台的任务。

  • 守护进程

    • 简介
        守护进程(daemon)是指在UNIX或其他多任务操作系统中在后台执行的电脑程序,并不会接受电脑用户的直接操控。此类程序会被以进程的形式初始化。守护进程程序的名称通常以字母“d”结尾:例如,syslogd就是指管理系统日志的守护进程。
    • 用户退出session之后,后台任务是否会继续执行是判定是否为“守护进程”的依据
        session推出之后,linux系统设计如下:

      session就是我们平常所说的终端窗口

      1. 用户准备退出 session
      2. 系统向该 session 发出SIGHUP信号
      3. session 将SIGHUP信号发给所有子进程
      4. 子进程收到SIGHUP信号后,自动退出

      • 前台任务会随着session的退出而退出是因为它收到了SIGHUP信号。
      • 后台任务是否会受到SIGNUP信号,取决于shell的 huponexit 参数。可以通过 $ shopt | grep huponexit 查看该参数的值。

        大多数Linux系统,这个参数默认关闭(off)。因此,session退出的时候,不会把SIGHUP信号发给”后台任务”,即此时的后台任务是守护进程,但这显然不够安全。

  • 更安全地创建守护进程: disown 命令
      通过”后台任务”启动”守护进程”并不保险,因为有的系统的huponexit参数可能是打开的(on)状态。
      更保险的方法是使用disown命令。它可以将指定任务从”后台任务”列表(jobs命令的返回结果)之中移除。一个”后台任务”只要不在这个列表之中,session 就肯定不会向它发出SIGHUP信号。

    $ node server.js &
    $ disown

      执行上面的命令以后,server.js进程就被移出了”后台任务”列表。你可以执行jobs命令验证,输出结果里面,不会有这个进程。
      但是,这样还存在问题。因为”后台任务”的标准 I/O 继承自当前 session,disown命令并没有改变这一点。一旦”后台任务”读写标准 I/O,就会发现它已经不存在了,所以就报错终止执行。
      为了解决这个问题,需要对”后台任务”的标准 I/O 进行重定向。

    $ node server.js > stdout.txt 2> stderr.txt < /dev/null &
    $ disown
  •   上面这样执行,基本上就没有问题了。

    • 更简便地创建守护进程: nohup 命令
      还有比disown更方便的命令,就是 nohup

      $ nohup node server.js &

      nohup命令对server.js进程做了三件事。

      1.阻止SIGHUP信号发到这个进程。
      2.关闭标准输入。该进程不再能够接收任何输入,即使运行在前台。
      3.重定向标准输出和标准错误到文件nohup.out。

        也就是说,nohup命令实际上将子进程与它所在的 session 分离了。
        注意,nohup命令不会自动把进程变为”后台任务”,所以必须加上&符号

  • 创建守护进程的其他思路:screentmux 命令
      在当前的session里面创建多个session。常用的有两种方法, screentmux 命令。

    • screen 命令(使用最普遍的守护进程创建方案)
        现在很多时候我们的开发环境都已经部署到云端了,直接通过SSH来登录到云端服务器进行开发测试以及运行各种命令,一旦网络中断,或者人为断开连接,通过SSH运行的命令也会退出,这个发让人发疯的。
        好在有screen命令,它可以解决这些问题。

      • 新建一个Screen Session(最好带上session的名称,注意参数S是大写的)
        $ screen -S screen_session_name
      • 将当前Screen Session放到后台,即回到创建新的session之前的session
        $ CTRL + AD
      • 唤起一个Screen Session,即进入创建的新session中
        screen -r screen_session_name
      • 终止一个session
        新的session中使用 ctrl+d 即可。

        上述步骤即可创建新的session,就可以在新的session中运行相应的指令。

    • tmux
      就是平时所说的分屏操作,但其实该命令更主要的是创建新的session。

      • 创建新的session(最好指定名字)
        tmux new -s session_name
      • 切换到指定session
        $ tmux attach -t session_name
      • 列出所有session
        $ tmux list-sessions
      • 退出当前session
        tmux detach 或者是 ctrl+bd