任务管理与守护进程【Linux】

文章目录

  • 进程组
  • 前台进程&后台进程
  • 守护进程
  • daemon

任务管理与守护进程【Linux】

进程组


组长是多个进程的第一个,组长进程的标识是,其进程组ID等于其进程ID

前台进程&后台进程

前台进程:能获取键盘输入,即拥有键盘文件
后台进程:不能获取键盘输入,即没有键盘文件

前台进程只能有一个,当一个进程变成前台进程后,bash会自动变为后台进程,此时bash就无法进行命令行解释了。
命令行中前台进程要一直存在 ,不能没有

ctrl + c,可以终止前台进程

./myprocess & ,加了& ,就变成后台进程了

[cxq@iZwz9fjj2ssnshikw14avaZ lesson31]$ ll
total 36
-rw-rw-r-- 1 cxq cxq    90 Jul 15 22:41 Makefile
-rwxrwxr-x 1 cxq cxq 26440 Jul 15 15:31 myprocess
-rw-rw-r-- 1 cxq cxq   443 Jul 15 22:41 mysignal.cc
-rw-rw-r-- 1 cxq cxq     0 Jul 14 16:59 test.c
[cxq@iZwz9fjj2ssnshikw14avaZ lesson31]$ ./myprocess &

Linux中,一次登陆中,一个终端,一般会配上一个bash,每一个登陆,只允讲一个进程是前台进程,但是可以允许多个进程是后台进程

[cxq@iZwz9fjj2ssnshikw14avaZ lesson43]$ ./process  >> log.txt & 
[1] 27184

1: 后台任务号
27184是进程pid

查看后台任务

[cxq@iZwz9fjj2ssnshikw14avaZ lesson43]$ jobs
[1]+  Running                 ./process >> log.txt &

fg,将一个在后台运行的作业(job)调回到前台继续执行

[cxq@iZwz9fjj2ssnshikw14avaZ lesson43]$ jobs
[1]+  Running                 ./process >> log.txt &
[cxq@iZwz9fjj2ssnshikw14avaZ lesson43]$ fg 1 

如果想要重新放回后台 ,ctrl + z

bg 命令用于将一个挂起(stopped)或暂停(suspended)的作业放入后台执行

[cxq@iZwz9fjj2ssnshikw14avaZ lesson43]$ jobs
[1]   Running                 ./process >> log.txt &
[2]-  Running                 ./process >> log.txt &
[3]+  Running                 ./process >> log1.txt &
[cxq@iZwz9fjj2ssnshikw14avaZ lesson43]$ fg 3
./process >> log1.txt
^Z
[3]+  Stopped                 ./process >> log1.txt
[cxq@iZwz9fjj2ssnshikw14avaZ lesson43]$ jobs 
[1]   Running                 ./process >> log.txt &
[2]-  Running                 ./process >> log.txt &
[3]+  Stopped                 ./process >> log1.txt
[cxq@iZwz9fjj2ssnshikw14avaZ lesson43]$ bg 3 
[3]+ ./process >> log1.txt &

守护进程


关闭xshell后 ,这几个进程TTY就没了 ,与终端无关了 ,PPID全部变成1 ,会话还是保留了关闭xshell前的会话ID,关闭xshell后 ,这几个进程的PID变化了,也就是说这几个进程会受到用户的登陆和注册的影响

守护进程化:不想受到任何用户登陆和注销的影响

守护进程 :自成进程组、自成会话的进程
守护进程的本质,就是孤儿进程

调用setsid创建新会话的目的,是让当前进程自成会话,与当前bash脱离关系

  pid_t setsid(void);

调用setsid创建新会话时,要求调用进程不能是进程组组长,但是当我们在命令行上启动多个进程协同完成某种任务时,其中第一个被创建出来的进程就是组长进程,因此我们需要fork创建子进程,让子进程调用setsid创建新会话并继续执行后续代码,而父进程我们直接让其退出即可

    //父进程退出 ,子进程创建新会话 
   if (fork() > 0)
        exit(0);
    setsid();

功能:网络版少数单词的翻译,涉及到守护进程
Daemon.hpp

#pragma once
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

const std::string nullfile = "/dev/null";
void Daemon(const std::string &cwd = "") // 设置空串为缺省值
{

    // 1. 忽略其他异常信号
    signal(SIGCLD, SIG_IGN);
    signal(SIGPIPE, SIG_IGN);
    signal(SIGSTOP, SIG_IGN);

    // 父进程退出 ,子进程创建新会话
    if (fork() > 0)
        exit(0);
    setsid();

    // 3. 更改当前调用进程的工作目录
    if (!cwd.empty()) // 不为空
    {
        chdir(cwd.c_str());
    }
    // 4. 标准输入,标准输出,标准错误重定向至/dev/null
  int fd =  open(nullfile.c_str(),O_RDWR ); 
      if(fd > 0)
    {
        dup2(fd, 0);
        dup2(fd, 1);
        dup2(fd, 2);
        close(fd);
    }
}

ls /proc/4686/fd -l, 系统会显示进程 ID 为 4686 的进程打开的所有文件描述符的详细信息

[cxq@iZwz9fjj2ssnshikw14avaZ lesson42]$  ps ajx | head -1  && ps ajx | grep Tcpserver 
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
    1  4686  4686  4686 ?           -1 Ssl   1001   0:00 ./Tcpserver 8888
27777 11212 11211 27777 pts/1    11211 S+    1001   0:00 grep --color=auto Tcpserver
[cxq@iZwz9fjj2ssnshikw14avaZ lesson42]$ ls /proc/4686/fd -l
total 0
lrwx------ 1 cxq cxq 64 Sep 16 12:36 0 -> /dev/null
lrwx------ 1 cxq cxq 64 Sep 16 12:36 1 -> /dev/null
lrwx------ 1 cxq cxq 64 Sep 16 12:36 2 -> /dev/null
lrwx------ 1 cxq cxq 64 Sep 16 12:36 3 -> socket:[5908905]

daemon

daemon,创建守护进程

int daemon(int nochdir, int noclose);
  • 如果参数nochdir为0,则将守护进程的工作目录该为根目录,否则不做处理。
  • 如果参数noclose为0,则将守护进程的标准输入、标准输出以及标准错误重定向到/dev/null,否则不做处理。
版权声明:如无特殊标注,文章均来自网络,本站编辑整理,转载时请以链接形式注明文章出处,请自行分辨。

本文链接:https://www.shbk5.com/dnsj/74721.html