我将有一个父进程用于处理Web服务器重新启动.它将通知孩子停止收听新的请求,孩子会发信号通知家长已经停止收听,然后家长会发信号通知新孩子它可以开始收听.通过这种方式,我们可以完成不到100毫秒的停机时间以重启该级别(我也有一个零停机时间的孙子重启,但这并不总是足够重启).
在关闭时,服务管理器将终止父服务器.孩子如何发现父母已经结束?
使用子进程的stdin和stdout发送信号.也许我可以检测到stdin流的结束?我希望避免轮询间隔.此外,如果可能的话,我希望这是一个非常快速的检测.
如果子进程的父进程突然终止而没有等待,会发生什么?孩子的过程也会死吗?
我有一个脚本,在后台启动另一个脚本,然后终止它.我期待儿童脚本消失,但最终仍然设法打印一些输出.这是一个例子:
在脚本one.sh:
echo "this is one"
./two.sh &
sleep 1
pid=$!
kill $pid
echo "this was one"
Run Code Online (Sandbox Code Playgroud)
在脚本two.sh:
echo "this is two"
./three.sh
echo "this was two"
Run Code Online (Sandbox Code Playgroud)
在脚本three.sh:
echo "this is three"
sleep 5
echo "this was three"
Run Code Online (Sandbox Code Playgroud)
我跑了./one.sh,它应该在后台运行two.sh,然后运行three.sh但不在后台运行!得到的输出是:
this is one
this is two
this is three
this was one
this was three
Run Code Online (Sandbox Code Playgroud)
不应该在输出中出现"this is three",因为three.sh没有在后台运行而two.sh被one.sh终止了?您是否也可以向我指出任何文档,这些文档描述了进程在后台(而非)在后台运行时的行为以及终止时会发生什么?
非常感谢您的帮助!
这些问题的过去答案都集中在分叉上:
对于这个问题,我只是询问对'系统'功能的调用.
假设我有一个名为sleep.pl的脚本:
use strict;
use warnings;
sleep(300);
Run Code Online (Sandbox Code Playgroud)
然后我有一个名为kill.pl的脚本
use strict;
use warnings;
system("sleep.pl");
Run Code Online (Sandbox Code Playgroud)
我运行kill.pl并使用ps我找到kill.pl的进程ID并杀死它(不使用kill -9,只是普通的kill)
sleep.pl还在睡觉.
我想我的问题的解决方案涉及一个SIG处理程序,但是我需要将什么内容放入处理程序来杀死子进程?
我有一个父进程可能产生许多子进程的情况.我想要实现的是,如果父进程被终止或者它退出,那么它的所有子进程应该与父进程终止.
在帖子(下面的链接)中,我找到了通过让父进程成为组长来存档的建议.如果我理解正确,这也是过程组的主要目的.我对吗?
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) 我有这个脚本命名wsjs.sh:
#!/bin/bash
WS=/home/user/wsjs
cd $WS
nohup atom . &
gnome-terminal
grunt watch
Run Code Online (Sandbox Code Playgroud)
如果我在bash中运行它:
./wsjs.sh
Run Code Online (Sandbox Code Playgroud)
然后原子编辑器,gnome-terminal分别启动,当前的bash显示:
user@ubuntu:~$ ./wsjs.pwd
nohup: appending output to ‘nohup.out’
Running "watch" task
Waiting...
Run Code Online (Sandbox Code Playgroud)
现在,如果我按ctrl + c,grunt watch退出,BUT原子编辑器也关闭.
......这很奇怪.
我在bash中手动输入了每个命令,并且原子未关闭.我用gedit替换了atom并运行脚本,它没有关闭.
为什么原子关闭了?谢谢!
我读了前面的问题fork和exec之间的差异,但它让我有些疑惑.
在使用fork()并且你对孩子调用exec时,创建的新进程exec仍然是孩子吗?
杀死父进程是否也杀死了孩子?
在顶部答案中显示的绘图/示例中,他调用wait/,waitpid因为如果父进程首先终止,子进程终止,然后您获得该ls命令的部分输出或没有输出,这是正确的吗?
通常,如果我通过以下方式创建进程:
Process proc = new ProcessBuilder("some_long_running_script.py").start();
Run Code Online (Sandbox Code Playgroud)
然后我的java程序完成,我可以看到脚本进程继续运行(如预期的那样)
但是,如果我然后添加代码:
proc.waitFor();
Run Code Online (Sandbox Code Playgroud)
然后在脚本完成之前杀死我的java程序,我可以看到脚本也死了(不像预期的那样).
这似乎是说"waitFor()"以某种方式将脚本进程与我的java进程合并,这是设计的吗?我似乎无法在文档中的任何地方看到它.
这可能是特定于操作系统吗 我在Mac Yosemite上运行
据我了解,在父进程死亡时终止子进程的最佳方法是通过prctl(PR_SET_PDEATHSIG)(至少在Linux上):How to make child process die afterparent exits?
对此有一个警告man prctl:
当执行 set-user-ID 或 set-group-ID 二进制文件或具有相关功能的二进制文件时(自 Linux 2.4.36 / 2.6.23 起),该值会被 fork(2) 的子进程清除(请参阅能力(7))。该值在 execve(2) 中保留。
因此,以下代码存在竞争条件:
父级.c:
#include <unistd.h>
int main(int argc, char **argv) {
int f = fork();
if (fork() == 0) {
execl("./child", "child", NULL, NULL);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
孩子.c:
#include <sys/prctl.h>
#include <signal.h>
int main(int argc, char **argv) {
prctl(PR_SET_PDEATHSIG, SIGKILL); // ignore error checking for now
// ...
return 0;
} …Run Code Online (Sandbox Code Playgroud) 我写了一个用fork()分解一些进程的程序.如果出现错误,我想杀死所有孩子和母亲的过程.如果我使用exit(EXIT_FAILURE),则仅杀死子进程.
我正在考虑一个系统("killall [program_name]"),但必须有一个更好的方法......
谢谢你们!伦纳特