Você está offline; aguardando reconexão

PROBLEMA: Filho Inherits identificadores indesejados durante a chamada de CreateProcess

IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine Translation ou MT), não tendo sido portanto traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes ao software de tradução automática (MT). Obrigado.

Clique aqui para ver a versão em Inglês deste artigo: 315939
Sintomas
Quando você cria um processo filho usando a função CreateProcess chamar em um ambiente multithreaded, a criança pode herdar alças que não foram se destina a ser herdada.
Causa
Esse comportamento pode ocorrer se dois threads simultaneamente criem processos filho e redirecionar as alças de DESVPAD por meio de pipes. Nesse cenário, há uma condição de corrida durante a criação dos pipes e dos processos, no qual é possível para um filho herdar identificadores de arquivo destinados-se a outro filho. Um thread cria os pipes e enquanto esse thread está no processo de criação do processo, outro segmento também está criando um processo filho. Todos os identificadores são herdáveis no aplicativo durante a chamada de CreateProcess são duplicados entre o processo filho.
Resolução
Para contornar esse problema, coloque o código de criação de filho em uma seção crítica. Isso impede que qualquer herança acidental. Para esse método funcione corretamente, crie os pipes como noninheritable definindo o descritor de segurança como NULL. Em seguida, defina as extremidades da conexão que você deseja o filho para herdar como herdáveis usando a chamada de função SetHandleInformation , conforme demonstrado no código de exemplo a seguir:
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);				
Observação que a solução anterior não vem sem custos. A criação de seções críticas no código, às vezes, é confusa e tem um preço de degradação do desempenho. Há outra solução alternativa para esse problema, e ele requer a criação de um aplicativo intermediário para iniciar o filho. No entanto, essa solução também tem a desvantagem. A principal desvantagem desse método é que o pai basicamente perde a facilidade com o qual ele obtém a identificação do processo. da criança Se o pai precisa a identificação do processo, o processo intermediário deve passar para ele volta alguma forma.

Usando esse método intermediário de aplicativo, você pode evitar qualquer herança acidental baseando-se no Windows para fazer o trabalho para você. Os identificadores herdados acidentalmente no processo de intermediário serão definitivamente não duplicados entre para o filho. Isso é garantido que se você especificar FALSO para o parâmetro bInheritHandles na chamada para CreateProcess no aplicativo intermediário. Seus identificadores de pipe ainda serão duplicados porque o Windows sempre duplicar identificadores STD, mesmo quando bInheritHandles está definida como FALSE.

Aplicativo pai

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);				

Aplicativo intermediário

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}				

Aviso: este artigo foi traduzido automaticamente

Propriedades

ID do Artigo: 315939 - Última Revisão: 11/21/2006 15:37:38 - Revisão: 4.1

Interface de Programação de Aplicativos do Microsoft Win32

  • kbmt kbapi kbkernbase kbprb kbthread KB315939 KbMtpt
Comentários