أنت غير متصل حاليًا، وفي انتظار الإنترنت الخاص بك ليقوم بإعادة الاتصال

PRB: التابع يرث مقابض غير مقصودة أثناء استدعاء CreateProcess

هام: تمت ترجمة هذا المقال باستخدام برنامج ترجمة آلية لشركة مايكروسوفت بدلاً من الاستعانة بمترجم بشري. تقدم شركة مايكروسوفت كلاً من المقالات المترجمة بواسطة المترجمين البشر والمقالات المترجمة آليًا وبالتالي ستتمكن من الوصول إلى كل المقالات الموجودة في قاعدة المعرفة الخاصة بنا وباللغة الخاصة بك. بالرغم من ذلك، فإن المقالة المترجمة آليًا لا تكون دقيقة دائمًا وقد تحتوي على أخطاء إملائية أو لغوية أو نحوية، مثل تلك الأخطاء الصادرة عن متحدث أجنبي عندما يتحدث بلغتك. لا تتحمل شركة مايكروسوفت مسئولية عدم الدقة أو الأخطاء أو الضرر الناتج عن أية أخطاء في ترجمة المحتوى أو استخدامه من قبل عملائنا. تعمل شركة مايكروسوفت باستمرار على ترقية برنامج الترجمة الآلية

اضغط هنا لرابط المقالة باللغة الانجليزية315939
الأعراض
عند إنشاء عملية تابعة باستخدام الدالة 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);				
ملاحظة لم تأتي الحل السابق دون التكاليف. إنشاء المقاطع الهامة في التعليمات البرمجية أحياناً messy ويتم يأتي وبسعر أداء منخفض. هناك حل آخر إلى هذه المشكلة ثم يتطلب إنشاء تطبيق الوسيطة لتشغيل التابع. على الرغم من ذلك، يحتوي هذا الحل أيضاً downside الخاص به. عيوب الرئيسي إلى هذا الأسلوب غير يفقد الأصل بشكل أساسي سهولة الذي يحصل على معرّف عملية التابع. إذا احتاج الأصل معرّف العملية, العملية المتوسطة يجب أن يمر عليه مرة أخرى ما.

باستخدام هذا الأسلوب التطبيق المتوسطة تجنب أي توريث غير المقصودة بواسطة الاعتماد على Windows القيام العمل نيابة عنك. أي مؤشر الموروثة بطريق الخطأ في العملية المتوسطة سوف حددت لا يمكن تكرار عبر إلى التابع. يتم ضمان إذا حددت معلمة bInheritHandles في استدعاء CreateProcess في تطبيق الوسيطة FALSE. سوف لا يزال يتم تكرار مقابض توجيه الإخراج لأن 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 - آخر مراجعة: 11/21/2006 15:37:38 - المراجعة: 4.1

Microsoft Win32 واجهة برمجة تطبيقات

  • kbmt kbapi kbkernbase kbprb kbthread KB315939 KbMtar
تعليقات
/html>body>