اقرأ في هذا المقال
إخراج الإدخال غير المتزامن هو شكل من أشكال معالجة إخراج الإدخال الذي يسمح للأجهزة الأخرى بإجراء المعالجة للبيانات قبل إجراء النقل أو نقل البيانات، يوجد هناك مشكلة في مزامنة إخراج الإدخال غير المتزامن، ليس من المؤكد أنّ البيانات الموجودة على ناقل البيانات حديثة أم أنّه ليس هناك فترة زمنية غير متاحة لإرسال البيانات أو استقبالها.
ما هو الإدخال / الإخراج المتزامن وغير المتزامن
هناك نوعان من مزامنة الإدخال / الإخراج (I/O): إدخال/إخراج (I/O) متزامن وإدخال/إخراج (I/O) غير متزامن، يشار إلى الإدخال/الإخراج غير المتزامن أيضًا باسم الإدخال/الإخراج المتراكب (overlapped I/O).
في إدخال/إخراج الملف المتزامن (synchronous file I/O)، يبدأ مؤشر ترابط عملية إدخال / إخراج ويدخل على الفور حالة انتظار حتى اكتمال طلب الإدخال / الإخراج، يرسل مؤشر الترابط الذي يقوم بتنفيذ إدخال/إخراج لملف غير متزامن طلب إدخال / إخراج إلى (kernel) عن طريق استدعاء وظيفة مناسبة.
إذا تمّ قبول الطلب من قبل (kernel)، يستمر مؤشر ترابط الاستدعاء في معالجة مهمة أخرى حتى تشير (kernel) إلى مؤشر الترابط بأنّ عملية الإدخال/الإخراج قد اكتملت، ثمّ يقطع وظيفته الحالية ويعالج البيانات من عملية الإدخال/الإخراج حسب الضرورة.
شرح الإدخال / الإخراج المتزامن وغير المتزامن
في الحالات التي يُتوقع فيها أن يستغرق طلب الإدخال/الإخراج قدرًا كبيرًا من الوقت، مثل التحديث أو النسخ الاحتياطي لقاعدة بيانات كبيرة أو ارتباط اتصالات بطيء، يعد الإدخال/الإخراج غير المتزامن طريقة جيدة بشكل عام لتحسين كفاءة المعالجة.
ومع ذلك، بالنسبة لعمليات الإدخال/الإخراج السريعة نسبيًا، فإنّ النفقات العامة لمعالجة طلبات إدخال/إخراج (kernel) وإشارات (kernel) قد تجعل الإدخال / الإخراج غير المتزامن أقل فائدة، خاصة إذا كان يلزم إجراء العديد من عمليات الإدخال/الإخراج السريعة.
في هذه الحالة، سيكون الإدخال/الإخراج المتزامن أفضل، تختلف الآليات وتفاصيل التنفيذ الخاصة بكيفية إنجاز هذه المهام حسب نوع مقبض الجهاز المستخدم والاحتياجات الخاصة للتطبيق، بعبارة أخرى، عادةً ما توجد طرق متعددة لحل المشكلة.
اعتبارات الإدخال / الإخراج المتزامن وغير المتزامن
إذا تمّ فتح ملف أو جهاز للإدخال / الإخراج المتزامن، أي، (FILE_FLAG_OVERLAPPED) غير محدد، فإنّ الاستدعاءات اللاحقة لوظائف مثل (WriteFile) يمكن أن تمنع تنفيذ مؤشر ترابط الاستدعاء حتى يحدث أحد الأحداث التالية:
- اكتمال عملية الإدخال / الإخراج، على سبيل المثال، “كتابة البيانات“.
- حدوث خطأ في الإدخال / الإخراج، على سبيل المثال، “أنبوب التجزئة (pipe) مغلق من الطرف الآخر”.
- حدث خطأ في الاستدعاء نفسه، على سبيل المثال، “معلمة (parameters) واحدة أو أكثر غير صالحة”.
- يستدعي مؤشر ترابط آخر في العملية الدالة (CancelSynchronousIo) باستخدام مؤشر ترابط مؤشر الترابط المحظور، والذي ينهي الإدخال / الإخراج لمؤشر الترابط هذا، ويفشل في عملية الإدخال / الإخراج.
- يتم إنهاء الثريد المحظور (blocked thread) بواسطة النظام؛ على سبيل المثال، يتم إنهاء العملية نفسها، أو يستدعي مؤشر ترابط آخر وظيفة (TerminateThread) باستخدام مقبض مؤشر الترابط المحظور، “يعتبر هذا بشكل عام الملاذ الأخير وليس تصميمًا جيدًا للتطبيق”.
في بعض الحالات، قد يكون هذا التأخير غير مقبول لتصميم التطبيق والغرض منه، لذلك يجب على مصممي التطبيقات التفكير في استخدام الإدخال / الإخراج غير المتزامن مع عناصر مزامنة مؤشر الترابط المناسبة مثل منافذ إكمال الإدخال / الإخراج (I/O completion ports).
تفتح العملية (process) ملفًا للإدخال / الإخراج غير المتزامن في استدعائها إلى (CreateFile) عن طريق تحديد علامة (FILE_FLAG_OVERLAPPED) في المعلمة (dwFlagsAndAttributes)، إذا لم يتم تحديد (FILE_FLAG_OVERLAPPED)، يتم فتح الملف من أجل الإدخال / الإخراج المتزامن، عند فتح الملف من أجل الإدخال / الإخراج غير المتزامن، يتم تمرير مؤشر إلى بنية (OVERLAPPED) في استدعاء ملف القراءة وملف الكتابة، عند تنفيذ عملية (I/O) متزامنة، هذه البنية غير مطلوبة في استدعاء (ReadFile و WriteFile).
شرح اعتبارات الإدخال / الإخراج المتزامن وغير المتزامن
على الرغم من أنّ (CreateFile) هي الوظيفة الأكثر شيوعًا لاستخدامها في فتح الملفات ووحدات تخزين القرص والأنابيب المجهولة (anonymous pipes) وغيرها من الأجهزة المماثلة، يمكن أيضًا إجراء عمليات الإدخال / الإخراج باستخدام نوع المقبض من عناصر النظام الأخرى مثل المقبض (socket) الذي تمّ إنشاؤه بواسطة المقبس أو قبول المهام.
يتم الحصول على مقابض عناصر الدليل عن طريق استدعاء الدالة (CreateFile) مع السمة (FILE_FLAG_BACKUP_SEMANTICS)، لا يتم استخدام مقابض الدليل مطلقًا، تطبيقات النسخ الاحتياطي هي أحد التطبيقات القليلة التي ستستخدمها عادةً، بعد فتح عنصر الملف من أجل الإدخال / الإخراج غير المتزامن، يجب إنشاء بنية (OVERLAPPED) بشكل صحيح وتهيئتها وتمريرها إلى كل استدعاء لوظائف مثل (ReadFile وWriteFile).
شروط استخدام البنية المتراكبة في عمليات القراءة والكتابة غير المتزامنة
ضع ما يلي في الاعتبار عند استخدام البنية المتراكبة (OVERLAPPED) في عمليات القراءة والكتابة غير المتزامنة:
- لا تقم بإلغاء تخصيص أو تعديل بنية (OVERLAPPED) أو المخزن المؤقت للبيانات حتى يتم إكمال كافة عمليات الإدخال / الإخراج غير المتزامنة إلى عنصر الملف.
- إذا قمت بتعريف المؤشر الخاص بك إلى بنية (OVERLAPPED) كمتغير محلي، لا تخرج من الدالة المحلية حتى يتم إكمال كافة عمليات الإدخال / الإخراج غير المتزامنة إلى عنصر الملف، إذا تمّ إنهاء الوظيفة المحلية قبل الأوان، فإنّ بنية (OVERLAPPED) ستخرج عن نطاقها وستكون غير قابلة للوصول إلى أي من وظائف (ReadFile) أو (WriteFile) التي تصادفها خارج تلك الوظيفة.
يمكنك أيضًا إنشاء حدث ووضع المقبض في بنية (OVERLAPPED)؛ يمكن بعد ذلك استخدام وظائف الانتظار لانتظار اكتمال عملية الإدخال / الإخراج بالانتظار على مقبض الحدث، كما ذكرنا سابقًا، عند العمل باستخدام مقبض غير متزامن، يجب أن تتوخى التطبيقات الحذر عند اتخاذ قرارات بشأن وقت تحرير الموارد المرتبطة بعملية إدخال / إخراج محددة على هذا المقبض، إذا تمّ إلغاء تخصيص المؤشر قبل الأوان، فقد يُعلم (ReadFile) أو (WriteFile) بشكل غير صحيح أنّ عملية الإدخال / الإخراج قد اكتملت.
علاوةً على ذلك، ستُرجع الدالة (WriteFile) أحيانًا (TRUE) بقيمة (GetLastError) لـ (ERROR_SUCCESS)، على الرغم من أنّها تستخدم مؤشرًا غير متزامن “والذي يمكنه أيضًا إرجاع (FALSE) مع (ERROR_IO_PENDING)”، عادةً ما يقوم المبرمجون الذين اعتادوا تصميم الإدخال / الإخراج المتزامن بإصدار موارد المخزن المؤقت للبيانات في هذه المرحلة لأنّ (TRUE وERROR_SUCCESS) تشير إلى اكتمال العملية.
ومع ذلك، إذا تمّ استخدام منافذ إكمال الإدخال / الإخراج مع هذا المعالج غير المتزامن، فسيتم أيضًا إرسال حزمة إكمال على الرغم من اكتمال عملية الإدخال / الإخراج على الفور، بمعنى آخر، إذا قام التطبيق بتحرير الموارد بعد إرجاع (WriteFile TRUE) مع (ERROR_SUCCESS) بالإضافة إلى روتين منفذ إكمال الإدخال / الإخراج، فسيكون له حالة مزدوجة خالية من الأخطاء، في هذا المثال، ستكون التوصية هي السماح لروتين منفذ الإكمال بأن يكون وحده المسؤول عن جميع عمليات تحرير هذه الموارد.
لا يحتفظ النظام بمؤشر الملف على المقابض غير المتزامنة للملفات والأجهزة التي تدعم مؤشرات الملفات “أي البحث عن الأجهزة”، لذلك يجب تمرير موضع الملف إلى وظائف القراءة والكتابة في أعضاء بيانات الإزاحة ذات الصلة في بنية (OVERLAPPED).