PRB: Figlio Inherits Handles imprevista durante la chiamata di CreateProcess

Traduzione articoli Traduzione articoli
Identificativo articolo: 315939 - Visualizza i prodotti a cui si riferisce l?articolo.
Espandi tutto | Chiudi tutto

In questa pagina

Sintomi

Quando si crea un processo figlio utilizzando la funzione CreateProcess chiamata che l'opzione in un ambiente multithreading, l'elemento figlio pu˛ ereditare un handle che non sono stati destinati a essere ereditata.

Cause

Questo comportamento pu˛ verificarsi se due thread creare processi figlio e reindirizzare i quadratini di STD tramite pipe contemporaneamente. In questo scenario, durante la creazione di pipe e processi, in cui Ŕ possibile che un elemento figlio di ereditare l'handle di file per il figlio di altri Ŕ presente una condizione di competizione . Un thread crea le pipe e mentre tale thread Ŕ in fase di creazione del processo, l'altro thread crea inoltre un processo figlio. Tutti gli handle sono ereditabili nell'applicazione durante la chiamata di CreateProcess vengono duplicati tra il processo figlio.

Risoluzione

Per aggirare il problema, Ŕ necessario inserire il codice di creazione del figlio in una sezione critica. In questo modo qualsiasi ereditarietÓ accidentale. Per questo metodo per il corretto funzionamento, Ŕ necessario creare la pipe come noninheritable, impostare il descrittore di protezione su NULL. Impostare quindi le estremitÓ della pipe che si desidera il figlio di ereditare come ereditabili mediante la chiamata di funzione SetHandleInformation , come illustrato nell'esempio di codice seguente:
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);
				
nota che la soluzione precedente non viene fornito senza i costi. La creazione di sezioni critiche nel codice a volte Ŕ complessa e viene fornito a un prezzo di riduzione delle prestazioni. ╚ presente un'altra soluzione al problema e richiede la creazione di un'applicazione intermedia per avviare l'elemento figlio. Tuttavia, questa soluzione presenta anche relativo svantaggio. Lo svantaggio principale di questo metodo Ŕ che l'elemento padre perda fondamentalmente la facilitÓ con cui viene ottenuto l'ID del processo. figlio Se l'elemento padre Ŕ l'ID di processo, il processo intermedio necessario passare nuovamente in qualche modo.

Utilizzando questo metodo di applicazione intermedio, Ŕ possibile evitare qualsiasi ereditarietÓ accidentali basandosi sulle operazioni per l'utente di Windows. Tutti gli handle ereditati accidentalmente nel processo di livello intermedio in modo definito non verranno duplicati tra al figlio. ╚ garantito che se si specifica FALSE per il parametro bInheritHandles nella chiamata a CreateProcess nell'applicazione intermedia. Gli handle di pipe ancora verranno duplicati perchÚ Windows sempre verrÓ duplicare gli handle di STD, anche quando bInheritHandles Ŕ impostata su FALSE.

Applicazione padre

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

Applicazione intermedia

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
}
				

ProprietÓ

Identificativo articolo: 315939 - Ultima modifica: martedý 21 novembre 2006 - Revisione: 4.1
Le informazioni in questo articolo si applicano a:
  • Microsoft Win32 Application Programming Interfaceáalle seguenti piattaforme
    • the operating system: Microsoft Windows XP
    • the operating system: Microsoft Windows 2000
    • Microsoft Windows NT 4.0
Chiavi:á
kbmt kbapi kbkernbase kbprb kbthread KB315939 KbMtit
Traduzione automatica articoli
Il presente articolo Ŕ stato tradotto tramite il software di traduzione automatica di Microsoft e non da una persona. Microsoft offre sia articoli tradotti da persone fisiche sia articoli tradotti automaticamente da un software, in modo da rendere disponibili tutti gli articoli presenti nella nostra Knowledge Base nella lingua madre dell?utente. Tuttavia, un articolo tradotto in modo automatico non Ŕ sempre perfetto. Potrebbe contenere errori di sintassi, di grammatica o di utilizzo dei vocaboli, pi¨ o meno allo stesso modo di come una persona straniera potrebbe commettere degli errori parlando una lingua che non Ŕ la sua. Microsoft non Ŕ responsabile di alcuna imprecisione, errore o danno cagionato da qualsiasi traduzione non corretta dei contenuti o dell?utilizzo degli stessi fatto dai propri clienti. Microsoft, inoltre, aggiorna frequentemente il software di traduzione automatica.
Clicca qui per visualizzare la versione originale in inglese dell?articolo: 315939
LE INFORMAZIONI CONTENUTE NELLA MICROSOFT KNOWLEDGE BASE SONO FORNITE SENZA GARANZIA DI ALCUN TIPO, IMPLICITA OD ESPLICITA, COMPRESA QUELLA RIGUARDO ALLA COMMERCIALIZZAZIONE E/O COMPATIBILITA' IN IMPIEGHI PARTICOLARI. L'UTENTE SI ASSUME L'INTERA RESPONSABILITA' PER L'UTILIZZO DI QUESTE INFORMAZIONI. IN NESSUN CASO MICROSOFT CORPORATION E I SUOI FORNITORI SI RENDONO RESPONSABILI PER DANNI DIRETTI, INDIRETTI O ACCIDENTALI CHE POSSANO PROVOCARE PERDITA DI DENARO O DI DATI, ANCHE SE MICROSOFT O I SUOI FORNITORI FOSSERO STATI AVVISATI. IL DOCUMENTO PUO' ESSERE COPIATO E DISTRIBUITO ALLE SEGUENTI CONDIZIONI: 1) IL TESTO DEVE ESSERE COPIATO INTEGRALMENTE E TUTTE LE PAGINE DEVONO ESSERE INCLUSE. 2) I PROGRAMMI SE PRESENTI, DEVONO ESSERE COPIATI SENZA MODIFICHE, 3) IL DOCUMENTO DEVE ESSERE DISTRIBUITO INTERAMENTE IN OGNI SUA PARTE. 4) IL DOCUMENTO NON PUO' ESSERE DISTRIBUITO A SCOPO DI LUCRO.

Invia suggerimenti

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com