Programing

Windows에서 자식 프로세스를 자동으로 제거하려면 어떻게합니까?

crosscheck 2020. 11. 21. 15:40
반응형

Windows에서 자식 프로세스를 자동으로 제거하려면 어떻게합니까?


C ++ Windows 앱에서 몇 가지 장기 실행 자식 프로세스를 시작합니다 (현재는 CreateProcess (...)를 사용하여이를 수행합니다.

주 프로세스가 충돌 하거나 닫힐 경우 자식 프로세스가 자동으로 닫히기를 원합니다 .

이것이 "부모"의 충돌을 위해 작동해야한다는 요구 사항 때문에, 운영 체제의 일부 API / 기능을 사용하여 수행해야한다고 생각합니다. 따라서 모든 "하위"프로세스가 정리됩니다.

어떻게해야합니까?


Windows API는 "작업 개체"라는 개체를 지원합니다. 다음 코드는 주 응용 프로그램이 종료 될 때 (핸들이 정리 될 때) 모든 프로세스를 종료하도록 구성된 "작업"을 만듭니다. 이 코드는 한 번만 실행해야합니다. :

HANDLE ghJob = CreateJobObject( NULL, NULL); // GLOBAL
if( ghJob == NULL)
{
    ::MessageBox( 0, "Could not create job object", "TEST", MB_OK);
}
else
{
    JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0 };

    // Configure all child processes associated with the job to terminate when the
    jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
    if( 0 == SetInformationJobObject( ghJob, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli)))
    {
        ::MessageBox( 0, "Could not SetInformationJobObject", "TEST", MB_OK);
    }
}

그런 다음 각 하위 프로세스가 생성되면 다음 코드를 실행하여 각 하위 프로세스를 시작하고 작업 개체에 추가합니다.

STARTUPINFO info={sizeof(info)};
PROCESS_INFORMATION processInfo;

// Launch child process - example is notepad.exe
if (::CreateProcess( NULL, "notepad.exe", NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo))
{
    ::MessageBox( 0, "CreateProcess succeeded.", "TEST", MB_OK);
    if(ghJob)
    {
        if(0 == AssignProcessToJobObject( ghJob, processInfo.hProcess))
        {
            ::MessageBox( 0, "Could not AssignProcessToObject", "TEST", MB_OK);
        }
    }

    // Can we free handles now? Not sure about this.
    //CloseHandle(processInfo.hProcess); 
    CloseHandle(processInfo.hThread);
}

VISTA 참고 : Vista 에서 AssignProcessToObject ()에 액세스 거부 문제가 발생하면 AssignProcessToJobObject가 Vista에서 항상 "액세스 거부"를 반환 합니다.


다소 험난한 해결책 중 하나는 부모 프로세스가 각 자식에 디버거로 연결하는 것입니다 ( DebugActiveProcess 사용 ). 디버거가 종료되면 모든 디 버기 프로세스도 종료됩니다.

더 나은 솔루션 (자식 프로세스도 작성했다고 가정)은 자식 프로세스가 부모를 모니터링하고 사라지면 종료하도록하는 것입니다.


Windows 작업 개체는 시작하기에 좋은 곳처럼 들립니다. 작업 개체의 이름은 잘 알려져 있거나 자식에게 전달 (또는 핸들 상속)되어야합니다. 실패한 IPC "하트 비트"또는 부모 프로세스 핸들의 WFMO / WFSO를 통해 부모가 죽었을 때 자식은이를 알 필요가 있습니다. 이 시점에서 모든 하위 프로세스는 TermianteJobObject를 사용하여 전체 그룹을 중단 할 수 있습니다.


별도의 감시 프로세스를 계속 실행할 수 있습니다. 유일한 작업은 현재 프로세스 공간을 관찰하여 설명하는 상황을 파악하는 것입니다. 충돌 후 원래 응용 프로그램을 다시 시작하거나 사용자에게 다른 옵션을 제공하거나 디버그 정보를 수집하는 등의 작업을 수행 할 수도 있습니다. 첫 번째 감시자가 두 번째 감시자가 필요하지 않도록 간단하게 유지하십시오.


You'd probably have to keep a list of the processes you start, and kill them off one by one when you exit your program. I'm not sure of the specifics of doing this in C++ but it shouldn't be hard. The difficult part would probably be ensuring that child processes are shutdown in the case of an application crash. .Net has the ability to add a function that get's called when an unhandled exception occurs. I'm not sure if C++ offers the same capabilities.


You could encapsulate each process in a C++ object and keep a list of them in global scope. The destructors can shut down each process. That will work fine if the program exits normally but it it crashes, all bets are off.

Here is a rough example:

class myprocess
{
public:
    myprocess(HANDLE hProcess)
        : _hProcess(hProcess)
    { }

    ~myprocess()
    {
        TerminateProcess(_hProcess, 0);
    }

private:
    HANDLE _hProcess;
};

std::list<myprocess> allprocesses;

Then whenever you launch one, call allprocessess.push_back(hProcess);


Just off the top of my head:

  • Have you considered using threads instead of processes?
  • Try passing the handle of the main thread/process to the child processes and get them to wait on that handle. This works for threads, as waiting on a thread handle waits until that thread completes and exits. Not too sure if it'll work for processes, should check out MSDN to verify this.

참고URL : https://stackoverflow.com/questions/53208/how-do-i-automatically-destroy-child-processes-in-windows

반응형