PRB: Podřízené dědí nežádoucímu popisovače během volání CreateProcess

Překlady článku Překlady článku
ID článku: 315939 - Produkty, které se vztahují k tomuto článku.
Rozbalit všechny záložky | Minimalizovat všechny záložky

Na této stránce

Příznaky

Při vytváření podřízený proces pomocí funkce CreateProcess volání v prostředí s více podprocesy, podřízené může dědit úchyty, které není určena k zděděná.

Příčina

K tomuto chování může dojít, pokud současně vytvořit podřízené procesy a přesměrovat úchyty STD prostřednictvím kanály dvou podprocesů. V tomto scénáři je spor během vytváření kanály a procesů, ve kterém je možné pro jednu podřízenou dědit určena pro ostatní podřízené popisovačů souboru. Jeden podproces vytvoří kanály a zatímco daný podproces je proces vytváření, ostatní podproces také vytváření podřízený proces. Všechny popisovače, které jsou v aplikaci během volání CreateProcess dědičná jsou duplikovány přes procesu podřízená.

Řešení

Chcete-li tento problém vyřešit, obtékání kód vytvoření podřízené kritická sekce. Tím se zabrání jakékoli náhodným dědičnosti. Tato metoda pracovat správně vytvořte kanály jako noninheritable nastavením popisovač zabezpečení NULL. Potom nastavte zakončení kanálu, který má podřízené dědí jako dědičná pomocí volání funkce SetHandleInformation jako znázorněn v následujícím ukázkovém kódu:
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);
				
poznámku, že se předcházející řešení nejsou přepnuty bez náklady. Vytváření kritické části kódu je někdy messy a pochází za cenu horší výkon. Existuje jiné řešení tohoto problému a vyžaduje vytvoření zprostředkující aplikace spustit podřízené. Toto řešení však má také jeho downside. Hlavní nevýhodou této metody je nadřazený ztratí podstatě snadnost, s jakou získá podřízený proces ID. Pokud nadřazený potřebuje ID procesu, zprostředkující proces musí projít jej zpět nějakým způsobem.

Pomocí této metody aplikace zprostředkující vyhnout libovolné náhodným dědičnosti podle použití Windows způsobem práce. Všechny omylem zděděné popisovače zprostředkující proces jednoznačně není být duplikována přes k podřízené. Toto je zaručena Pokud NEPRAVDA určíte pro parametr bInheritHandles ve volání CreateProcess zprostředkující aplikace. Úchyty kanálu bude duplikován stále protože Windows bude vždy duplicitní úchyty STD, i když bInheritHandles je nastavena na hodnotu FALSE.

Nadřazené aplikace.

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

Zprostředkující aplikací

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
}
				

Vlastnosti

ID článku: 315939 - Poslední aktualizace: 21. listopadu 2006 - Revize: 4.1
Informace v tomto článku jsou určeny pro produkt:
  • Microsoft Win32 Application Programming Interface na těchto platformách
    • the operating system: Microsoft Windows XP
    • the operating system: Microsoft Windows 2000
    • Microsoft Windows NT 4.0
Klíčová slova: 
kbmt kbapi kbkernbase kbprb kbthread KB315939 KbMtcs
Strojově přeložený článek
Důležité: Tento článek byl přeložen pomocí software společnosti Microsoft na strojový překlad, ne profesionálním překladatelem. Společnost Microsoft nabízí jak články přeložené překladatelem, tak články přeložené pomocí software na strojový překlad, takže všechny články ve Znalostní databázi (Knowledge Base) jsou dostupné v češtině. Překlad pomocí software na strojový překlad ale není bohužel vždy dokonalý. Obsahuje chyby ve skloňování slov, skladbě vět, nebo gramatice, podobně jako když cizinci dělají chyby při mluvení v češtině. Společnost Microsoft není právně zodpovědná za nepřesnosti, chyby nebo škody vzniklé chybami v překladu, nebo při použití nepřesně přeložených instrukcí v článku zákazníkem. Společnost Microsoft aktualizuje software na strojový překlad, aby byl počet chyb omezen na minimum.
Projděte si také anglickou verzi článku:315939

Dejte nám zpětnou vazbu

 

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