c-子进程不应与父进程一起消亡



以下场景:

  • process_1.bin启动doSomeThing.sh

  • doSomeThing.sh应该先杀死process_1.bin,但继续运行自己并做一些其他事情

我尝试过fork、exec、screen、p_threads、daemon和一些,但都没有成功。每次doSomeThing.sh启动并杀死process_1.bin时,它都会杀死自己,因为父进程被杀死了。

CCD_ 7告诉我:;终止信号后离开程序">

不幸的是,这也不起作用:

pid_t pid;
pid = fork();
if (pid < 0)
exit(EXIT_FAILURE);
if (pid > 0)            // Success: Let the parent terminate
exit(EXIT_SUCCESS);
if (setsid() < 0)
exit(EXIT_FAILURE);
pid = fork();
if (pid < 0)
exit(EXIT_FAILURE);
if (pid > 0)
exit(EXIT_SUCCESS);

//     umask(0);  
// chdir("/");
switch(pid)
{
case -1: // Fork() has failed
perror ("fork");
break;
case 0: // This is processed by the child
// deamon(0,0);            
system("/root/doSomeThing.sh");
// system("screen -dmS doSomeThing /root/doSomething.sh")
//     char *name[] = {
//    "/bin/bash",
//    "-c",
//    "/root/doSomeThing.sh",
//    NULL
//    };
//     if(execvp(name[0], name) < 0)
//       perror("execvp");
exit(0);
break;
default:    // This is processed by the parrent
break;
}

我如何指挥doSomeThing.sh杀死process_1.bin,但仍然活着?

除了按照Jonathan Leffler的建议忽略SIGTERM之外,您还可以使子进程成为守护进程,这样它的生命将独立于父进程的生命。Linux有一个命令,可以将进程作为守护进程守护进程或库函数启动,以便程序愿意与其父进程及其控制终端守护进程分离。

您的子进程不应该正在消亡。这里有两个shell脚本模拟您所描述的内容。

process1.bin

#!/bin/sh
echo "$0: at work"
trap 'echo "$0: Death threat received"; exit 1' 1 2 3 13 15
sh doSomething.sh &
echo "$0: so far, so good"
wait
echo "$0: it's sad when all your children die"
ps -f
echo "$0: exiting normally"
exit 0

做某事.sh

#!/bin/sh
#
# Commit parenticide and continue, preferably without dying.
#PPID=$(ps -fp$$ | colnum -c 3)
echo "Before"
ps -f
(
set -x
kill $PPID
)
sleep 1
echo ""
echo "After"
ps -f
sleep 5
echo "$0: Goodbye, Cruel World!"

有一次,当我运行它时,我得到了输出:

$ ./process1.bin
./process1.bin: at work
./process1.bin: so far, so good
Before
UID   PID  PPID   C STIME   TTY           TIME CMD
501   649   641   0  9:58AM ttys000    0:00.14 -bash
501 29760   649   0  8:47AM ttys000    0:00.01 sh
501 29793 29760   0  8:47AM ttys000    0:00.01 /bin/sh ./process1.bin
501 29794 29793   0  8:47AM ttys000    0:00.01 sh doSomething.sh
501   661   657   0  9:58AM ttys001    0:00.05 -bash
501   693   688   0  9:58AM ttys002    0:00.05 -bash
501   738   731   0  9:58AM ttys007    0:00.31 -bash
501   769   766   0  9:58AM ttys008    0:00.05 -bash
501   848   847   0  9:58AM ttys009    0:00.05 -bash
501   884   881   0  9:58AM ttys010    0:00.12 -bash
501   946   920   0  9:58AM ttys011    0:00.15 -bash
+ kill 29793
./process1.bin: Death threat received
$ 
After
UID   PID  PPID   C STIME   TTY           TIME CMD
501   649   641   0  9:58AM ttys000    0:00.14 -bash
501 29760   649   0  8:47AM ttys000    0:00.01 sh
501 29794     1   0  8:47AM ttys000    0:00.01 sh doSomething.sh
501   661   657   0  9:58AM ttys001    0:00.05 -bash
501   693   688   0  9:58AM ttys002    0:00.05 -bash
501   738   731   0  9:58AM ttys007    0:00.31 -bash
501   769   766   0  9:58AM ttys008    0:00.05 -bash
501   848   847   0  9:58AM ttys009    0:00.05 -bash
501   884   881   0  9:58AM ttys010    0:00.12 -bash
501   946   920   0  9:58AM ttys011    0:00.15 -bash
doSomething.sh: Goodbye, Cruel World!
$

请注意,我的$提示出现在"收到死亡威胁"之后。以下输出来自doSomething;我在"再见,残酷的世界!"以获得最终的CCD_ 12提示。

在运行macOS Catalina 10.15.7的MacBook Pro上使用Bash进行测试。


在一条评论中,oemer_11907说:

shell脚本杀死所有进程来播放更新(包括C更新进程(。一旦C更新进程被shell更新进程终止,它就会向其所有子进程发送一个SIGTERM。因此,shell脚本也被杀死。如果它只是计算而不杀死它的父对象,那么它就会一直运行到最后。

如果父进程向其所有子进程发送SIGTERM,则子脚本doSomething.sh必须使用以下任一项忽略SIGTERM信号:

trap "" 15
trap "" TERM

在它向其父级发送信号之前。或者父进程可以安排不向该子进程发送信号。或者它可以安排孩子在执行SIGTERM之前忽略它:

signal(SIGTERM, SIG_IGN);
…exec child…

或者…

最新更新