2017-01-02 7 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); 죽여라. (appPID) ... ' –

+0

강제로 죽이기를 원 하시겠습니까? 아니면 아이들이 자연스럽게 닫힐 때까지 메인 프로그램을 살아있게 하시겠습니까? http://stackoverflow.com/a/23587108/1457000 죽이기에 대한 대답입니다 (동일한 기능을 D에서 사용할 수 있습니다 .... 오, 당신은 높은 수준의 기능을 사용하고 있으므로 전화를 할 수 없습니다. 올바른 장소. 대답으로 게시하기 전에 이것을 재고해야합니다.) 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는 필요한 기능을 수행합니다. 물론

,이 신호를 송신 한 후, 자녀가 기본 종료보다 더 우아하게 종료하지만,이 프로그램을 시도하고 cat 실행을 볼 수자는 동안 ps을 실행 한 후 고양이가 때 사망 통지하는 것을 처리 할 수 ​​있습니다 부모가 종료합니다.

+0

덩크 아담, 이건 정말 흥미 롭습니다 만, 오늘 제 리눅스 지식을 다소 웃도는 것 같습니다. 예제 코드를 이해하는 경우 mySpawnedProcess를 사용하여 내 자신의 PID를 가져 오지만 자식의 PID가 없으므로 스레드간에 통신 할 수 있습니다. 그러나 내가 fork() 행 위의 로컬 변수를 가지고 있고 포크 후에 parent pid를 지정하면 해당 pid를 부모에게 알리거나 전달하기 위해 자식이 액세스 할 수 있습니까? 다음, 새로운 일, prctl (..) 그리고 내가 사용할 수있는 것을 이해함에 따라 ... 내 질문에 대한 대답.코드를 파고 더 테스트 해 보겠습니다. –

+0

'fork'는 * child * pid를 리턴하므로,'mySpawnProcess'의 리턴 값은 부모 프로세스에 대한 자식의 PID입니다. 그래서 당신은 이미 그것을 가지고 있습니다 .. –