2017-01-02 123 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。所以你已經擁有它了.. –