DetailPage-MSS-KB

Knowledge Base

Artikel-ID: 315939 - Geändert am: Dienstag, 21. November 2006 - Version: 4.1

 

Auf dieser Seite

Problembeschreibung

Beim Erstellen eines untergeordneten Prozesses rufen Sie mithilfe der CreateProcess -Funktion in einer Multithreadumgebung auf, das untergeordnete Element kann Handles, die nicht geerbt werden, erben.

Ursache

Dieses Verhalten kann auftreten, wenn zwei Threads gleichzeitig untergeordnete Prozesse erstellen und die STABW Handles über Pipes leiten. In diesem Szenario besteht eine Racebedingung während der Erstellung der Pipes und Prozesse, in denen es möglich, für ein Kind zum Erben von Dateihandles, die für die anderen untergeordneten vorgesehen ist. Ein Thread erstellt die Pipes und während der Thread ist der Erstellung des Prozesses, ist der andere Thread auch das einen untergeordneten Prozess erstellen. Alle Handles, die in der Anwendung während der CreateProcess -Aufruf vererbbare werden an den untergeordneten Prozess über dupliziert.

Lösung

Binden Sie, um dieses Problem zu umgehen, den Erstellung von untergeordneten Code in einen kritischen Abschnitt. Dadurch werden alle versehentliche Vererbung. Erstellen Sie für diese Methode funktioniert die Pipes als noninheritable, indem Sie die Sicherheitsbeschreibung auf NULL. Legen Sie dann das Ende der Pipe, die die untergeordneten, als vererbbar erben mithilfe des SetHandleInformation -Funktionsaufrufs, wie im folgenden Beispielcode gezeigt werden sollen:
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);
				
Hinweis, dass die vorherige Lösung nicht ohne Kosten stammen. Die Erstellung von kritischen Abschnitten im Code ist manchmal unübersichtlich und zu einem Preis Leistungsminderung kommt. Es ist eine andere Problemumgehung für dieses Problem und erfordert die Erstellung einer intermediate Anwendung, starten Sie das untergeordnete Element. Diese Lösung hat jedoch den Nachteil. Der Hauptnachteil dieser Methode ist, dass das übergeordnete Element die Benutzerfreundlichkeit im Grunde verliert mit der er die untergeordneten Prozess-ID erhält Wenn das übergeordnete Element die Prozess-ID benötigt, muss der intermediate Prozess es wieder irgendwie übergeben.

Durch Verwendung dieser Methode intermediate Anwendung vermeiden Sie eine versehentliche Vererbung auf Windows, um die Arbeit für Sie tun. Alle versehentlich geerbte Handles im intermediate-Prozess werden definitiv nicht über für die untergeordnete dupliziert werden. Dadurch ist gewährleistet, wenn Sie falsch für den bInheritHandles -Parameter im Aufruf von CreateProcess in die intermediate Anwendung angeben. Die Pipe-Handles werden noch dupliziert werden, weil Windows immer die Ziehpunkte STD duplizieren wird, auch wenn die bInheritHandles auf FALSE festgelegt ist.

Übergeordnete Anwendung

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

Intermediate-Anwendung

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
}
				

Die Informationen in diesem Artikel beziehen sich auf:
  • Microsoft Win32 Application Programming Interface, wenn verwendet mit:
    • the operating system: Microsoft Windows XP
    • the operating system: Microsoft Windows 2000
    • Microsoft Windows NT 4.0
Keywords: 
kbmt kbapi kbkernbase kbprb kbthread KB315939 KbMtde
Maschinell übersetzter ArtikelMaschinell übersetzter Artikel
Wichtig: Dieser Artikel wurde maschinell und nicht von einem Menschen übersetzt. Die Microsoft Knowledge Base ist sehr umfangreich und ihre Inhalte werden ständig ergänzt beziehungsweise überarbeitet. Um Ihnen dennoch alle Inhalte auf Deutsch anbieten zu können, werden viele Artikel nicht von Menschen, sondern von Übersetzungsprogrammen übersetzt, die kontinuierlich optimiert werden. Doch noch sind maschinell übersetzte Texte in der Regel nicht perfekt, insbesondere hinsichtlich Grammatik und des Einsatzes von Fremdwörtern sowie Fachbegriffen. Microsoft übernimmt keine Gewähr für die sprachliche Qualität oder die technische Richtigkeit der Übersetzungen und ist nicht für Probleme haftbar, die direkt oder indirekt durch Übersetzungsfehler oder die Verwendung der übersetzten Inhalte durch Kunden entstehen könnten.
Den englischen Originalartikel können Sie über folgenden Link abrufen: 315939  (http://support.microsoft.com/kb/315939/en-us/ )
Microsoft stellt Ihnen die in der Knowledge Base angebotenen Artikel und Informationen als Service-Leistung zur Verfügung. Microsoft übernimmt keinerlei Gewährleistung dafür, dass die angebotenen Artikel und Informationen auch in Ihrer Einsatzumgebung die erwünschten Ergebnisse erzielen. Die Entscheidung darüber, ob und in welcher Form Sie die angebotenen Artikel und Informationen nutzen, liegt daher allein bei Ihnen. Mit Ausnahme der gesetzlichen Haftung für Vorsatz ist jede Haftung von Microsoft im Zusammenhang mit Ihrer Nutzung dieser Artikel oder Informationen ausgeschlossen.
Freigeben
Weitere Supportoptionen
Microsoft Community-Supportforen
Kontaktieren Sie uns direkt
Zertifizierten Partner finden
Microsoft Store
Folgen Sie uns: