DetailPage-MSS-KB

기술 자료

기술 자료: 315939 - 마지막 검토: 2006년 11월 21일 화요일 - 수정: 4.1

 

이 페이지에서

현상

자식 프로세스를 만들 때 다중 스레드 환경에서 CreateProcess 함수를 사용하여 호출, 자식 상속될 수 의도한 있던 핸들을 상속할 수 있습니다.

원인

두 스레드가 동시에 자식 프로세스가 만들어 파이프를 통해 STD 핸들을 리디렉션하는 경우 이 문제가 발생할 수 있습니다. 이 시나리오에서는 경우 경쟁 조건이 파이프와 [NULL]에 대해 다른 자식 위한 파일 핸들을 상속할 한 자식 가능성이 프로세스를 만드는 동안 파이프, 하나의 스레드를 만들고 해당 스레드가 프로세스를 만드는 프로세스에 있는 동안에는 다른 스레드가 자식 프로세스 또한 만드는 것입니다. 상속 가능한 CreateProcess 호출하는 동안 응용 프로그램에서 핸들이 모두 자식 프로세스 간에 복제됩니다.

해결 방법

이 문제를 해결하려면 자식 생성 코드가 임계 영역에서 래핑하십시오. 실수로 상속을 금지합니다. 이 메서드는 제대로 작동하려면 noninheritable 같이 파이프 보안 설명자를 NULL로 설정하여 만듭니다. 그런 다음 원하는 대로 상속 가능한 SetHandleInformation 함수 호출을 사용하여 다음 예제 코드와 같이 상속하는 자식 파이프 끝에 설정합니다:
CRITICAL_SECTION    cs;
HANDLE              hReadIn, hWriteIn;
HANDLE              hReadOut, hWriteOut;
HANDLE              hReadErr, hWriteErr;

InitializeCriticalSection(&cs);

EnterCriticalSection(&cs);

if ( !CreatePipe(&hReadIn, &hWriteIn, NULL, 0) )
{
    // an error occurred
}

if ( !CreatePipe(&hReadOut, &hWriteOut, NULL, 0) )
{
    // an error occurred
}

if ( !CreatePipe(&hReadErr, &hWriteErr, NULL, 0) )
{
    // an error occurred
}

if ( !SetHandleInformation(hReadIn, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT) )
{
    // an error occurred
}

if ( !SetHandleInformation(hWriteOut, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT) )
{
    // an error occurred
}

if ( !SetHandleInformation(hWriteErr, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT) )
{
    // an error occurred
}

STARTUP_INFO        si;
PROCESS_INFORMATION pi;

si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = hReadIn;
si.hStdOutput = hWriteOut;
si.hStdError = hWriteErr;

if ( !CreateProcess( "child.exe",
                     NULL,
                     NULL, NULL,
                     TRUE,
                     NORMAL_PRIORITY_CLASS,
                     lpEnvironment,
                     &si, &pi) )
{
    // an error occurred
}

CloseHandle(hReadIn);
CloseHandle(hWriteOut);
CloseHandle(hWriteErr);

LeaveCriticalSection(&cs);
				
노트 앞의 솔루션 비용 없이 제공됩니다. 코드의 임계 경우가 복잡해져서 있습니다 만들고 성능이 가격으로 제공됩니다. 다른 해결 방법은 이 문제점에 및 자식 시작하도록 중간 응용 프로그램 작성이 필요합니다. 그러나 이 솔루션은 또한 해당 단점은 있습니다. 이 메서드는 주 단점은 부모 자식 프로세스 ID를 얻는 손쉬운 기본적으로 잃을 것입니다. 부모 프로세스 ID를 하는 경우 중간 프로세스의 이를 다시 어떤 식으로든 전달해야 합니다.

이 중간 응용 프로그램 메서드를 사용하여 실수로 상속을 작업을 수행하려면 Windows 의존하지 마십시오. 중간 프로세스의 모든 실수로 상속된 핸들은 한정적으로 걸쳐 있는 자식 중복될 수 됩니다지 않습니다. FALSE CreateProcess 호출에서 중간 응용 에서 bInheritHandles 매개 변수에 지정하면 이 보장됩니다. FALSE로 bInheritHandles 설정한 경우에도 Windows STD 핸들을 항상 중복 됩니다 때문에 파이프 핸들이 여전히 중복될 수 있습니다.

부모 응용 프로그램

HANDLE              hReadIn, hWriteIn;
HANDLE              hReadOut, hWriteOut;
HANDLE              hReadErr, hWriteErr;

if ( !CreatePipe(&hReadIn, &hWriteIn, NULL, 0) )
{
    // an error occurred
}

if ( !CreatePipe(&hReadOut, &hWriteOut, NULL, 0) )
{
    // an error occurred
}

if ( !CreatePipe(&hReadErr, &hWriteErr, NULL, 0) )
{
    // an error occurred
}

STARTUP_INFO        si;
PROCESS_INFORMATION pi;

si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = hReadIn;
si.hStdOutput = hWriteOut;
si.hStdError = hWriteErr;

if ( !CreateProcess( "Intermediate.exe",
                     NULL,
                     NULL, NULL,
                     TRUE,
                     NORMAL_PRIORITY_CLASS,
                     lpEnvironment,
                     &si, &pi) )
{
    // an error occurred
}

CloseHandle(hReadIn);
CloseHandle(hWriteOut);
CloseHandle(hWriteErr);
				

중간 응용 프로그램

STARTUP_INFO        si;
PROCESS_INFORMATION pi;

si.cb = sizeof(si);

if ( !CreateProcess( "child.exe",
                     NULL,
                     NULL, NULL,
                     FALSE,
                     NORMAL_PRIORITY_CLASS,
                     lpEnvironment,
                     &si, &pi) )
{
    // an error occurred
}
				

본 문서의 정보는 다음의 제품에 적용됩니다.
  • Microsoft Win32 Application Programming Interface 을(를) 다음과 함께 사용했을 때
    • the operating system: Microsoft Windows XP
    • the operating system: Microsoft Windows 2000
    • Microsoft Windows NT 4.0
키워드: 
kbmt kbapi kbkernbase kbprb kbthread KB315939 KbMtko
기계 번역된 문서기계 번역된 문서
중요: 본 문서는 전문 번역가가 번역한 것이 아니라 Microsoft 기계 번역 소프트웨어로 번역한 것입니다. Microsoft는 번역가가 번역한 문서 및 기계 번역된 문서를 모두 제공하므로 Microsoft 기술 자료에 있는 모든 문서를 한글로 접할 수 있습니다. 그러나 기계 번역 문서가 항상 완벽한 것은 아닙니다. 따라서 기계 번역 문서에는 마치 외국인이 한국어로 말할 때 실수를 하는 것처럼 어휘, 구문 또는 문법에 오류가 있을 수 있습니다. Microsoft는 내용상의 오역 또는 Microsoft 고객이 이러한 오역을 사용함으로써 발생하는 부 정확성, 오류 또는 손해에 대해 책임을 지지 않습니다. Microsoft는 이러한 문제를 해결하기 위해 기계 번역 소프트웨어를 자주 업데이트하고 있습니다.
공유
추가 지원 옵션
Microsoft Community 지원 포럼
직접 문의하기
Microsoft Certified Partner 찾기
Microsoft Store
소기업이 아닙니까?
다음에서 팔로우하십시오.