فئة الموضوع في دلفي
رابتور [الاستوديو العقلي]
http://mental.mentu.com
ثالث
بعد الحديث عن المنشئ، دعونا نلقي نظرة على المدمر:
destructor TThread.Destroy;
يبدأ
إذا (FThreadID <> 0) وليس FFinished بعد ذلك
يبدأ
إنهاء؛
إذا FCreateSuspending ثم
سيرة ذاتية؛
انتظر؛
نهاية؛
إذا كان FHandle <> 0 ثم CloseHandle(FHandle);
التدمير الموروث؛
FFatalException.Free;
RemoveThread;
نهاية؛
قبل تحرير كائن مؤشر الترابط، تحقق أولاً مما إذا كان مؤشر الترابط لا يزال قيد التنفيذ. إذا كان مؤشر الترابط لا يزال قيد التنفيذ (معرف مؤشر الترابط ليس 0، ولم يتم تعيين علامة نهاية مؤشر الترابط)، فسيتم استدعاء عملية الإنهاء لإنهاء مؤشر الترابط. تقوم عملية الإنهاء ببساطة بتعيين علامة الإنهاء لفئة مؤشر الترابط، كما في الكود التالي:
الإجراء TThread.Terminate؛
يبدأ
Fterminated := True;
نهاية؛
لذلك، يجب أن يستمر تنفيذ الخيط حتى ينتهي بشكل طبيعي، بدلاً من إنهاء الخيط على الفور.
القليل من الاستطراد هنا: لقد سألني العديد من الأشخاص عن كيفية إنهاء سلسلة رسائل "فورًا" (بالطبع، في إشارة إلى المواضيع التي تم إنشاؤها باستخدام TThread). بالطبع لا يعمل! الطريقة الوحيدة لإنهاء سلسلة رسائل هي السماح لطريقة التنفيذ بإكمال التنفيذ، لذلك بشكل عام، إذا كنت تريد إنهاء سلسلة المحادثات الخاصة بك في أقرب وقت ممكن، فيجب عليك التحقق باستمرار من علامة الإنهاء في طريقة التنفيذ خلال فترة زمنية قصيرة لذلك أنه يمكنك الخروج في الوقت المناسب. هذا مبدأ مهم جدًا عند تصميم التعليمات البرمجية المترابطة!
بالطبع، إذا كان يجب أن تكون قادرًا على الخروج من مؤشر الترابط "على الفور"، فإن فئة TThread ليست خيارًا جيدًا، لأنه إذا كنت تستخدم واجهة برمجة التطبيقات (API) لإنهاء مؤشر الترابط بالقوة، فلن يتم تحرير كائن مؤشر ترابط TThread بشكل صحيح في النهاية، و سيحدث انتهاك الوصول عند تدمير الكائن. في هذه الحالة، يمكنك فقط استخدام وظائف API أو RTL لإنشاء سلاسل الرسائل.
إذا كان مؤشر الترابط في حالة تعليق بدء التشغيل، فقم بنقل مؤشر الترابط إلى حالة التشغيل، ثم اتصل بـ WaitFor للانتظار، وتتمثل وظيفته في الانتظار حتى انتهاء مؤشر الترابط قبل متابعة التنفيذ. سيتم شرح تنفيذ WaitFor لاحقًا.
بعد انتهاء الخيط، أغلق مقبض الخيط (يوجد المقبض ضمن إنشاء الخيط العادي) ثم حرر كائن الخيط الذي أنشأه نظام التشغيل.
ثم اتصل بـ TObject.Destroy لتحرير هذا الكائن وتحرير كائن الاستثناء الذي تم التقاطه، وأخيرًا اتصل بـ RemoveThread لتقليل عدد مؤشرات الترابط في العملية.
الجوانب الأخرى المتعلقة بالتعليق/الاستئناف وإعدادات أولوية مؤشر الترابط ليست محور هذه المقالة ولن يتم مناقشتها مرة أخرى. ما سيتم مناقشته أدناه هو التركيزان الآخران في هذه المقالة: المزامنة والانتظار.
ولكن قبل تقديم هاتين الوظيفتين، يجب تقديم تقنيتين أخريين لمزامنة الخيط: الأحداث والأقسام المهمة.
الأحداث تختلف عن الأحداث في دلفي. في جوهر الأمر، الحدث يعادل متغيرًا منطقيًا عالميًا. وله عمليتان للتخصيص: Set وReset، وهما يعادلان ضبطه على True أو False. ويتم التحقق من قيمتها من خلال عملية WaitFor. وفقًا لنظام التشغيل Windows، هناك ثلاث وظائف لواجهة برمجة التطبيقات: SetEvent وResetEvent وWaitForSingleObject (هناك العديد من واجهات برمجة التطبيقات التي تنفذ وظيفة WaitFor، وهذه هي أبسطها).
هذه العناصر الثلاثة هي عناصر أولية، لذلك يمكن للحدث تنفيذ التطبيقات في سلاسل عمليات متعددة لا تستطيع المتغيرات المنطقية العامة تنفيذها. لقد تم ذكر وظائف Set وReset من قبل، والآن دعونا نتحدث عن وظيفة WaitFor:
تتمثل وظيفة WaitFor في التحقق مما إذا كانت حالة الحدث هي حالة Set (أي ما يعادل True)، وإذا لم يكن الأمر كذلك، فإنه ينتظر أن يتغير إلى حالة Set أثناء فترة الانتظار استدعاء مؤشر الترابط WaitFor في حالة تعليق. بالإضافة إلى ذلك، يحتوي WaitFor على معلمة لإعداد المهلة. إذا كانت هذه المعلمة 0، فإنها لا تنتظر وتعيد حالة الحدث على الفور. إذا كانت INFINITE، فإنها تنتظر إلى ما لا نهاية حتى تحدث حالة التعيين ينتظر العدد المقابل من المللي ثانية ثم قم بإرجاع حالة الحدث.
عندما ينتقل الحدث من حالة إعادة التعيين إلى حالة التعيين، فإنه يقوم بتنشيط سلاسل الرسائل الأخرى المعلقة بسبب حدث WaitFor، ولهذا السبب يطلق عليه اسم الحدث. يشير ما يسمى بـ "الحدث" إلى "انتقال الدولة". يمكن تمرير معلومات "انتقال الحالة" هذه بين سلاسل الرسائل من خلال الأحداث.
بالطبع، يمكن أيضًا تحقيق وظيفة مماثلة باستخدام متغير منطقي محمي (انظر مقدمة القسم المهم أدناه)، طالما تم استبدال WaitFor بحلقة من التعليمات البرمجية التي تتحقق من القيمة المنطقية. من الناحية الوظيفية لا توجد مشكلة على الإطلاق، ولكن في الاستخدام الفعلي ستجد أن مثل هذا الانتظار سيشغل الكثير من موارد وحدة المعالجة المركزية، ويقلل من أداء النظام، ويؤثر على سرعة تنفيذ الخيوط الأخرى، لذلك فهو غير اقتصادي، بل وربما يكون هناك في بعض الأحيان مشاكل. لذا لا ينصح باستخدامه بهذه الطريقة.
(يتبع)