سؤال

أنا أعمل حاليًا على آلية IPC استنادًا إلى الأنابيب المسماة باستخدام منفذ إكمال IO.

لسوء الحظ ، لدي بعض المشاكل في وثائق MSDN لأنه من غير الواضح تمامًا بالنسبة لي أن الحالات التي تستدعيها إلى READFILE/WRITEFILE تؤدي إلى حزمة إكمال.

الحالة عندما يتم إرجاع خطأ مع error_io_pending تكون واضحة ، ولكن ماذا عن الحالة الممكنة على ما يبدو ، عند إرجاع error_more_data؟ هل ستكون هناك حزمة إكمال في هذه الحالة؟ علاوة على ذلك ، ماذا لو تم إرجاع أخطاء أخرى؟ في أي حالات يجب أن أتعامل مع النتيجة والموارد المجانية مباشرة وليس في معالج الانتهاء؟

ستكون هناك حالة أخرى إذا نجحت ReadFile/WriteFile ، وهو أمر ممكن على ما يبدو أيضًا. MSDN هو لحسن الحظ واضح جدا حول هذا هنا:

علاوة على ذلك ، ستعود وظيفة WriteFile في بعض الأحيان بشكل صحيح مع قيمة getLasterror لـ error_success ، على الرغم من أنها تستخدم مقبضًا غير متزامن (والذي يمكن أن يعود أيضًا مع error_io_pending). ... في هذا المثال ، ستكون التوصية هي السماح لروتين منفذ الإكمال بأن يكون مسؤولاً فقط عن جميع عمليات تحرير هذه الموارد.

هل هذه التوصية صحيحة في جميع الحالات ، ويمكن أن يتم تجاهل (وينبغي) في الواقع نتيجة لعملية إعادة القراءة/الكتابة للمقابض المخصصة لمنفذ الإنجاز؟

هل كانت مفيدة؟

المحلول

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

هناك مشكلة رسم الخرائط بين NTSTATUS الرموز التي يتم إرجاعها بواسطة نظام IO ورموز الأخطاء Win32 التي تجعل من الصعب معرفة الحالات التي هي الأخطاء والتي هي فقط إعلامية. NTSTATUS, ، والتي تستخدمها kernel و API الأصلي ، لديها أربعة مستويات من الشدة: النجاح والمعلومات والتحذير والخطأ. أي شيء سوى رمز الخطأ يشير إلى أن عملية IO كانت قادرة على البدء. Win32 لديه شدة واحدة فقط (ERROR_*) ، لذلك كان لا بد من تعيين النجاح والمعلومات ورموز التحذير إلى جانب رموز الخطأ.

  • ERROR_IO_PENDING - STATUS_PENDING هي حالة النجاح
  • ERROR_MORE_DATA - STATUS_BUFFER_OVERFLOW تحذير أو STATUS_MORE_ENTRIES حالة النجاح

يمكنك تجاهل أي رموز غير رموز التي يعود إليها أو تكتبها وتتوقع عنصر إكمال في قائمة الانتظار ، ولكن تحديد أي شيء يمكن أن يكون جزءًا من الألم. سيكون من الرائع إذا تم تنظيم رموز الخطأ Win32 بشكل أفضل ، لكن Microsoft تقدم رسم خرائط من NTSTATUS إلى رموز الخطأ WIN32: http://support.microsoft.com/kb/113996. نرى ntstatus.h في النظام الأساسي SDK أو التثبيت VS الخاص بك لتحديد شدة أ NTSTATUS الرمز هو.

من الممكن إكمال عملية IO عند إرجاع مكالمة API الأصلية ، على سبيل المثال طلب قراءة تم نسخه للتو من ذاكرة التخزين المؤقت (لا شيء للانتظار بشكل غير متزامن). ستظل رسالة الانتهاء في قائمة الانتظار في مثل هذه الحالات من أجل الاتساق.

نصائح أخرى

  • نعم ، من الممكن تمامًا ذلك ERROR_MORE_DATA يمكن أن تأتي في حزمة الانتهاء. يجب أن تكون دائمًا مستعدًا للتعامل مع أي أخطاء محتملة. في الوثائق GetQueuedCompletionStatus من الواضح أنه عندما تعود FALSE, ، يجب عليك التحقق مما إذا كان lpOverlapped المعلمة هي NULL. إذا لم يكن كذلك NULL, ، تحتوي حزمة إكمال I/O على خطأ.

  • السلوك الافتراضي هو أن يتم وضع حزمة إكمال في قائمة الانتظار حتى منفذ الانتهاء حتى عندما تكون عندما ReadFile أو WriteFile إرجاع TRUE. بدءًا من Windows Vista ، يمكن تغيير هذه السياسة. انظر الوثائق على SetFileCompletionNotificationModes.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top