現在オフラインです。再接続するためにインターネットの接続を待っています

PRB: 予期しない処理 CreateProcess の呼び出し時に子を継承します。

重要: このサポート技術情報 (以下「KB」) は、翻訳者による翻訳の代わりに、マイクロソフト機械翻訳システムによって翻訳されたものです。マイクロソフトは、お客様に、マイクロソフトが提供している全ての KB を日本語でご利用いただけるように、翻訳者による翻訳 KB に加え機械翻訳 KB も提供しています。しかしながら、機械翻訳の品質は翻訳者による翻訳ほど十分ではありません。誤訳や、文法、言葉使い、その他、たとえば日本語を母国語としない方が日本語を話すときに間違えるようなミスを含んでいる可能性があります。マイクロソフトは、機械翻訳の品質、及び KB の内容の誤訳やお客様が KB を利用されたことによって生じた直接または間接的な問題や損害については、いかなる責任も負わないものとします。マイクロソフトは、機械翻訳システムの改善を継続的に行っています。

315939
現象
使用して子プロセスを作成するときに、 CreateProcess 関数呼び出しマルチ スレッド環境では、子に継承されることを意図していないハンドルを継承可能性があります。
原因
この動作は 2 つのスレッドが同時に子プロセスを作成し、パイプを通じて STD ハンドルをリダイレクトする場合に発生します。このシナリオでは、 レース 作成時に条件のパイプとプロセスの他の子のためのファイル ハンドルを継承する子の 1 つです。パイプ、1 つのスレッドを作成し、スレッドは、プロセスを作成するのですが、他のスレッドも、子プロセスの作成です。中に、アプリケーションが継承するすべてのハンドルは、 CreateProcess 呼び出しが複製で、子プロセスに。
解決方法
この問題を回避するには、クリティカル セクションで、子作成コードをラップします。これにより、偶発的な継承されなくなります。このメソッドを正しく動作させるのには、セキュリティ記述子を 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 中間のアプリケーションにします。STD ハンドルを常に 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 - 最終更新日: 07/25/2011 00:47:00 - リビジョン: 6.0

  • kbthread kbapi kbkernbase kbprb kbmt KB315939 KbMtja
フィードバック