OS——进程间关系与守护进程

张开发
2026/4/19 22:16:34 15 分钟阅读

分享文章

OS——进程间关系与守护进程
进程组进程组是一个或者多个进程的集合。每个进程除了pidppid之外还有pgid这个属性即进程组id它表示该进程属于哪个进程组在多进程任务中第一个被创建的进程是组长进程组长进程的pid就是本组的pgid。而子进程也会继承父进程的pgid但可以通过setpgid函数改变如果不能修改的话所有的进程就都成bash的组员了。需要说明的是进程组会在组中所有进程都退出了之后销毁至于组长是否提前退出对于组的存在是没有影响的。会话当我们使用xshell登录云服务器成功后云服务器上的sshd服务会做这样的事情启动一个bash进程相当于linux的命令行以及一个终端文件。然后调用setsid函数设置bash进程的会话id即SID一般来说就是会话中的第一个进程组的组长进程的pid结果如下上面sshd服务所做的工作其实就是在linux系统中创建一个session由于进程间继承的缘故bash进程创建的所有任务进程组包含的进程的SID都是bash进程最初设置的SID。所以逻辑上这些进程组属于同一个会话bash不直接从网络中读取xshell发送过来的命令而是从终端文件中读取输出执行结果的时候也直接输出到终端文件中。sshd服务会将命令解密后打在终端文件并将结果加密后返回给xshell。会话中的所有进程组都可以向终端文件写入但同一时刻只有一个进程组可以读取终端文件可以读取终端文件的进程组叫做前台进程组其他所有进程组都叫做后台进程组。初始时前台进程组是bash。所以一但我们在bash上启动前台进程bash将无法读取其他命令和接收信号直到bash重新变成前台进程。整个示意图可以如下表示下面是查看终端文件的方法我们甚至可以直接往终端文件中写数据也会被对应的bash拿到作业控制作业是对于用户来说对于linux系统来说其实就是进程组。下面是对于作业的控制操作fg 作业号 //将作业放到前台运行 bg 作业号 //让后台暂停的作业重新运行 jobs //查看当前会话的所有作业 ctrlZ //暂停前台作业并将其变成后台作业 //这几个命令互相配合实现作业控制实操作业的状态如下守护进程首先要区分一个概念把一个进程变成守护进程并不是说把它变成后台进程因为不论是前台进程还是后台进程bash进程一旦销毁他们就都成了孤儿进程难免会收到影响可能是终止也可能是其他影响并且即使他们的暂时没被销毁但会话ID仍然是原来的SID一但OS以后清理会话就会把守护进程也杀死。而守护进程指的是不被任何其他进程所影响默默运行的一种进程。把一个进程变成守护进程本质上就是让该进程从当前会话中脱离出来其实就是让其自成一个会话。下面是把一个进程变成守护进程的函数只要调用它进程就变成守护进程const char* root /; const char* dev_null /dev/null; void Daemon(bool ischdir, bool isclose) { // 1. 忽略可能引起程序异常退出的信号不止这三个 signal(SIGCHLD, SIG_IGN); signal(SIGPIPE, SIG_IGN); signal(SIGHUP, SIG_IGN) // 2. 让自己不要成为组长因为规定调用setsid的进程不能是组长进程 if (fork() 0) exit(0); // 3. 设置让自己成为一个新的会话 后面的代码其实是子进程在走 setsid(); // 4.守护进程一般有自己的工作目录可以选择是否将当前进程的 CWD 更改成为根目录 if (ischdir) chdir(root); // 5. 可以选择是否关闭默认输入输出流 if (isclose) { close(0); close(1); close(2); } else { //如果怕关闭会导致守护进程读写失败而崩溃可以用这种/dev/null是linux中的特殊文件读不到内容写了的数据会被丢弃 int fd open(dev_null, O_RDWR); if (fd 0) { dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); close(fd); } } }调用该函数之后进程会变成孤儿进程因为我们是创建了子进程然后直接让父进程退出。

更多文章