PRB: 子系繼承非預期的控點 CreateProcess 呼叫期間

文章翻譯 文章翻譯
文章編號: 315939 - 檢視此文章適用的產品。
全部展開 | 全部摺疊

在此頁中

徵狀

當您建立子處理序是利用 CreateProcess 函式呼叫在多執行緒環境中,子可能會繼承已不適合被繼承的控點。

發生的原因

如果兩個執行緒同時建立子處理程序,並重新導向標準控點,透過管道,就會發生這種行為。在這種情況下沒有 競爭 情形管道和裡面是可能繼承適用於其他子系的檔案控制代碼的一個子系的處理序建立過程。一個執行緒會建立管道] 及 [當該執行緒建立處理程序的程序中時另一個執行緒也建立子處理序。是可繼承 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 bInheritHandles 參數 CreateProcess 來呼叫,中間應用程式中。因為 Windows 將會永遠重複標準] 控點,甚至 bInheritHandles 設為 FALSE 時,仍將能複製管道控點。

父應用程式

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
}
				

屬性

文章編號: 315939 - 上次校閱: 2006年11月21日 - 版次: 4.1
這篇文章中的資訊適用於:
  • 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 KbMtzh
機器翻譯
重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。
按一下這裡查看此文章的英文版本:315939
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。

提供意見

 

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