2017-12-04 10 views
2

boost::process::child을 기다리는 동안 그것이 "정상적으로 종료했는지"종료했는지 어떻게 알 수 있습니까?boost :: process 프로세스가 "정상적으로 또는 정상적으로 종료"했을 때 어떻게 알 수 있습니까?

의이 나는이 과정이를 작성한다고 가정 해 봅시다 :

boost::process::child child("myprg.exe", "5000"); 
child.wait(); 
int res = child.exit_code(); 

을 myprg.exe은 여기서

int main(int argc, char* argv[]) 
{ 
    if (argc == 2) 
    { 
     boost::this_thread::sleep(boost::posix_time::milliseconds(atoi(argv[1]))); 
     return 1; 
    } 

    return 0; 
} 

참고 : 말도 안돼 이것을 MCVE을, 나는 성공적인 경우 0을 반환해야합니다 주요 동의합니다.

은 내가 어떻게 알 수 있습니다, 그것은 (예 또는 Windows 프로세스 관리자에 대한 child.terminate 사용) 기다리는 동안 누군가가 프로세스를 종료하는 경우 child.exit_code()이 1 일 때, child.exit_code()는, 결국, 그래서 1

를 반환 볼 이것이 프로세스의 메인 엔트리 함수에 의해 반환 된 값이거나 프로세스가 종료 된 경우?

1은 프로세스가 종료되었음을 의미합니까? 그런 다음 프로그램은 1을 반환하지 말아야하며이 종료 코드를 유지하여 사망 한 특수한 상황을 식별하고 정상적으로 종료하지 않아야합니다.

그렇지 않은 경우 boost::process API는 프로세스가 정상적으로 종료되었는지 또는 죽었는지 알 수 있습니까?

+0

플랫폼에 독립적 인 방법은 없지만 프로세스 그룹을 사용하고 CHLD 신호를 처리 할 수 ​​있다는 것을 기억하십시오. 즉, Boost Process API의 추상화가 깨졌습니다. – sehe

답변

2

결국 child.exit_code()이 1 일 때 프로세스의 주 항목 함수에서 반환 한 값인지 또는 프로세스가 종료 된 경우 알 수 있습니까?

수 없습니다.

1은 프로세스가 종료되었음을 의미합니까?

에 달려 있습니다. Windows는, this에 의하면 답 1이지만, 어디에도 기재되어 있지 않습니다. 종료 된 프로세스의 리턴 코드는 프로세스를 종료하는 인스턴스에 의해 결정됩니다. 부스트의 종료 기능을 위해, 하나는 세부/창/terminate.hpp 내부에 발견 :

inline void terminate(child_handle &p) 
{ 
    if (!::boost::winapi::TerminateProcess(p.process_handle(), EXIT_FAILURE)) 
     boost::process::detail::throw_last_error("TerminateProcess() failed"); 

    ::boost::winapi::CloseHandle(p.proc_info.hProcess); 
    p.proc_info.hProcess = ::boost::winapi::INVALID_HANDLE_VALUE_; 
} 

는 그래서 하나의 프로세스가 어떤 값을 반환 할 수 있습니다, 그러나 1이 될 수있는, 항상 EXIT_FAILURE을 반환합니다.

프로세스가 정상적으로 종료되었는지 여부를 완전히 완벽하고 완벽하게 구분할 수 있도록하려면 반환 코드를 평가하는 것 외에도 고유 한 통신 메커니즘을 구현해야합니다.

0

자식 프로세스에서 오류 처리기를 설정하여 다른 종료 코드를 반환 할 수 있습니다. 예를 들어 STL 라이브러리에 std::set_terminate을 추가하십시오.

int main(int argc, char* argv[]) 
{ 
    std::set_terminate([](){ exit(2); }); 
    if (argc == 2) 
    {   
     boost::this_thread::sleep(boost::posix_time::milliseconds(atoi(argv[1]))); 
     return 1; 
    } 
    return 0; 
}