2017-01-02 125 views
0

我遇到了我的应用程序和spawnProcess的问题。 如果主应用程序由于某种原因死亡/被杀死,那么产生的进程似乎依然存在,除非我使用终端通过它们的PID杀死它们,否则我无法到达它们。我的目标是,如果主应用程序死亡,那么产生的进程也应该被终止,不知何故。当主进程突然死亡时,我该如何杀死linux spawnProcess?

我的代码是这样的

auto appPid = spawnProcess("path/to/process"); 
scope(exit){ auto exitcode = wait(appPid); 
stderr.writeln(...);} 

如果我用同样的方式,当主进程死掉,使用wait(thisProcessID)我得到一个错误。 “没有超载匹配”。任何想法如何解决这个问题?

+0

通过同样的方法,我的意思是'scope(exit){wait(thisProcessID); kill(appPID)...' –

+0

你想让它强行杀死它们还是让主程序保持活着直到孩子自然关闭? http://stackoverflow.com/a/23587108/1457000是一个杀的答案(相同的功能可以使用从D ....哦poop你使用高级功能,所以你不能注入该呼叫正确的地方,我需要重新考虑这一点之前发布作为答案)。你的等待将不起作用,因为spawnProcess返回一个魔术类,并且thisProcessId只返回一个int。等待期待班级。但除此之外,等待只对我认为的孩子,而不是父母... –

+0

嗨,亚当,我不在乎如何接近,但软性更好。 –

回答

0

下面是一些将在Linux上执行的代码。它没有stdlib的spawnProcess的所有功能,它只是显示了基本的基础知识,但是如果你需要更多的东西,从这里扩展它并不难。

import core.sys.posix.unistd; 

version(linux) { 
     // this function is Linux-specific 
     import core.stdc.config; 
     import core.sys.posix.signal; 
     // we can tell the kernel to send our child process a signal 
     // when the parent dies... 
     extern(C) int prctl(int, c_ulong, c_ulong, c_ulong, c_ulong); 
     // the constant I pulled out of the C headers 
     enum PR_SET_PDEATHSIG = 1; 
} 

pid_t mySpawnProcess(string process) { 
     if(auto pid = fork()) { 
       // this branch is the parent, it can return the child pid 
       // you can: 
       // import core.sys.posix.sys.wait; 
       // waitpid(this_ret_value, &status, 0); 
       // if you want the parent to wait for the child to die 
       return pid; 
     } else { 
       // child 

       // first, tell it to terminate when the parent dies 
       prctl(PR_SET_PDEATHSIG, SIGTERM, 0, 0, 0); 

       // then, exec our process 
       char*[2] args; 
       char[255] buffer; 
       // gotta copy the string into another buffer 
       // so we zero terminate it and have a C style char**... 
       buffer[0 .. process.length] = process[]; 
       buffer[process.length] = 0; 
       args[0] = buffer.ptr; 

       // then call exec to run the new program 
       execve(args[0], args.ptr, null); 
       assert(0); // never reached 
     } 
} 

void main() { 
     mySpawnProcess("/usr/bin/cat"); 
     // parent process sleeps for one second, then exits 
     usleep(1_000_000); 
} 

所以下级功能需要使用,但Linux确实有一个功能,做你所需要的。

当然,因为它发出了一个信号,你的孩子可能要处理,要关闭更优雅比默认的终止,但试试这个程序并运行ps而它睡觉,看cat运行,然后注意到猫死时父母退出。

+0

Thks Adam,这真的很有意思,尽管今天在我的linux知识上有点过分。 如果我理解你的示例代码,使用mySpawnedProcess来获得我自己的pid,但是我没有孩子的pid,这样我可以在线程之间进行通信。然而,如果我有一个局部变量在fork()行之上,并且在fork之后,我将它分配给了父pid,那么是否可以通过child来使用它来通知/发信号给它的pid的父对象? 然后,对我来说,一个新的东西,prctl(..),也正如我理解我可以使用的东西,......我的问题的答案。深入挖掘你的代码并测试更多 –

+0

'fork'返回* child * pid,所以'mySpawnProcess'的返回值是父进程的子进程的PID。所以你已经拥有它了.. –