回到我年轻的时候,Unix是新事物,创建一个在你退出时没有被杀的过程是一个挑战.我们使用nohup命令来保护我们的持久进程免受HUP
信号的影响.如果我们不小心,我们的进程会在我们注销时被杀死,甚至关闭我们启动它们的shell.
快进到今天,我发现我很惊讶默认情况恰恰相反.在Ubuntu和Red Hat系统上,我发现我几乎可以在后台放置任何进程,杀死父shell,注销,任何事情都会继续.我看到了与Bash脚本,Python脚本和C程序相同的行为.我从xterm或ssh会话中获得相同的行为.
例如,在xterm或ssh窗口中,键入:
while [ 1 ]; do date; sleep 10; done > /tmp/out &
Run Code Online (Sandbox Code Playgroud)
现在从另一个窗口运行
tail -f /tmp/out
Run Code Online (Sandbox Code Playgroud)
观察它每10秒打印一次日期,然后用Ctrl-D关闭原始父shell.仍在运行.退出并重新登录.仍在运行.
发送HUP
信号,它立即死亡.
我可以使用Python脚本或C程序表现出相同的行为.睡不与无关.例如,这个丑陋的C程序表现相同:
#include <stdio.h>
void main() {
while(1) {
printf("*\n");
fflush(stdout);
int i, j, k = 0;
for(i=0; i < 10000; i++) {
for(j=0; j < 100000; j++) {
k += i * j;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这完全违背了我年轻时的方式.我想我刚才没注意到它改变了吗?那里的历史学家都知道这发生的时间?是否HUP
甚至被用于此目的?
如果确实这是事物的当前状态,我的问题是:当用户注销或断开连接时,如何安排流程死亡?
我有一个黑客,需要注意ppid
(父母的pid)改变,但肯定有一些比这更优雅的东西.
我有一个父进程可能产生许多子进程的情况.我想要实现的是,如果父进程被终止或者它退出,那么它的所有子进程应该与父进程终止.
在帖子(下面的链接)中,我找到了通过让父进程成为组长来存档的建议.如果我理解正确,这也是过程组的主要目的.我对吗?
Post也提到了prctl(PR_SET_PDEATHSIG,SIGHUP); 和其他一些方法,但它们是以太网操作系统特定的,否则不会如此优雅.
我已经写了一个小的演示来试图更好地理解事物,但它并不像我期望的那样工作.我究竟做错了什么?
//https://www.andrew.cmu.edu/course/15-310/applications/homework/homework4/terminalgroups1.html
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <stddef.h>
#include <errno.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <sys/termios.h>
int main()
{
int status;
int cpid;
int ppid;
ppid = getpid();
printf("parent: %d\n", ppid);
if (!(cpid=fork()))
{
printf("child: %d\n", getpid());
if(setpgid(0,ppid) == -1)
printf("child setpgid errno %s\n", strerror(errno));
else
printf("child gid %d\n", getpgid(0));
pause();
printf("child exited\n");
exit (-1);
}
if (cpid < 0)
exit(-1);
setpgid(0, ppid);
if(setpgid(0,0) == -1)
printf("parent setpgid erno %s\n", strerror(errno));
else …
Run Code Online (Sandbox Code Playgroud) 在类 Unix 操作系统中,如果一个进程pid
和它pgid
的进程相等,那么这个进程就是一个进程组长。
但是,如果进程领导者已经退出,而同一组中的其他进程仍在运行,那么谁是后续的领导者进程?