Проблема: Дочерние Inherits неправильный маркеры во время вызова CreateProcess

Переводы статьи Переводы статьи
Код статьи: 315939 - Vizualiza?i produsele pentru care se aplic? acest articol.
Развернуть все | Свернуть все

В этой статье

Проблема

При создании дочернего процесса, используяCreateProcessвызов функции в многопоточной среде, дочерний элемент может наследовать дескрипторов, которые не были предназначены для наследования.

Причина

Это может происходить, если два потока одновременно создавать дочерние процессы и перенаправить дескрипторы STD через каналы. В этом случае естьсостояние гонкисостояние во время создания каналов и процессов, в котором возможна один дочерний элемент для наследования дескрипторов файлов, предназначенных для других дочерних. Один поток создает каналы, и в то время как поток находится в процессе создания процесса, другой поток при создании дочернего процесса. Все дескрипторы, которые являются наследуемыми приложения во время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);
				
Обратите внимание, что предыдущие решения не переходит в без затрат. Создание критических разделов в коде иногда является сложной и поставляется по цене от низкой производительности. Имеется другое решение этой проблемы, и он требует создания промежуточного приложения для запуска дочернего элемента. Тем не менее это решение также имеет недостаток его. Главным недостатком этого метода является что родительской сущности теряет простота, с которым он получает идентификатор дочернего процесса. Если родительский идентификатор процесса, промежуточный процесс должен передавать его назад каким-либо образом.

С помощью этого метода промежуточного приложения, можно избежать любой случайного наследования полагаясь на Windows, чтобы сделать работу. Все случайно унаследованные дескрипторы в процессе промежуточного будет определенно не может повторяться через для дочернего элемента. Это гарантируется, что если указано значение FALSE дляbInheritHandlesпараметр в вызовеCreateProcessпромежуточного приложения. Дескрипторам канала будут дублироваться по-прежнему, потому что Windows будет всегда дублирование дескрипторов STD, даже если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 - Последний отзыв: 23 ноября 2010 г. - Revision: 2.0
Информация в данной статье относится к следующим продуктам.
  • Microsoft Win32 Application Programming Interface
Ключевые слова: 
kbapi kbkernbase kbprb kbthread kbmt KB315939 KbMtru
Переведено с помощью машинного перевода
ВНИМАНИЕ! Перевод данной статьи был выполнен не человеком, а с помощью программы машинного перевода, разработанной корпорацией Майкрософт. Корпорация Майкрософт предлагает вам статьи, переведенные как людьми, так и средствами машинного перевода, чтобы у вас была возможность ознакомиться со статьями базы знаний KB на родном языке. Однако машинный перевод не всегда идеален. Он может содержать смысловые, синтаксические и грамматические ошибки, подобно тому как иностранец делает ошибки, пытаясь говорить на вашем языке. Корпорация Майкрософт не несет ответственности за неточности, ошибки и возможный ущерб, причиненный в результате неправильного перевода или его использования. Корпорация Майкрософт также часто обновляет средства машинного перевода.
Эта статья на английском языке:315939

Отправить отзыв

 

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