فئة الموضوع في دلفي
رابتور [الاستوديو العقلي]
http://mental.mentu.com
(واحد)
هناك فئة خيط TThread في دلفي تُستخدم لتنفيذ برمجة متعددة الخيوط. تذكر معظم كتب دلفي ذلك، ولكنها تقدم في الأساس مقدمة موجزة للعديد من أعضاء فئة TThread، ثم تشرح وظيفة التنفيذ والاستخدام اكتمال المزامنة. ومع ذلك، هذا ليس كل ما يتعلق بالبرمجة متعددة الخيوط. الغرض من كتابة هذه المقالة هو استكمال ذلك.
مؤشر الترابط هو في الأساس جزء من التعليمات البرمجية التي تعمل بشكل متزامن في العملية. تحتوي العملية على خيط واحد على الأقل، يسمى الخيط الرئيسي. يمكن أيضًا أن يكون هناك عدة سلاسل فرعية في نفس الوقت. عندما يتم استخدام أكثر من مؤشر ترابط واحد في عملية ما، فإن ذلك يسمى "تعدد مؤشرات الترابط".
إذن كيف يتم تعريف ما يسمى بـ "جزء من الكود"؟ في الواقع، إنها وظيفة أو عملية (لدلفي).
إذا كنت تستخدم Windows API لإنشاء سلسلة رسائل، فسيتم تنفيذها من خلال وظيفة API تسمى CreateThread، والتي يتم تعريفها على النحو التالي:
التعامل مع إنشاء الموضوع(
LPSECURITY_ATTRIBUTES lpThreadAttributes،
دي وورد dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress،
LPVOID معلمة lp,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);
كما تقول أسمائهم، فإن المعلمات هي: سمات مؤشر الترابط (تستخدم لتعيين سمات أمان مؤشر الترابط تحت NT، غير صالحة تحت 9X)، وحجم المكدس، وعنوان البداية، والمعلمات، وعلامة الإنشاء (تُستخدم لتعيين حالة مؤشر الترابط عند إنشائه)، ومعرف مؤشر الترابط، وأخيرا إرجاع مقبض الخيط. عنوان البداية هو مدخل وظيفة الخيط، حتى تنتهي وظيفة الخيط، ينتهي الخيط.
عملية تنفيذ الموضوع بأكمله هي كما يلي:
نظرًا لأن CreateThread يحتوي على العديد من المعلمات وهو واجهة برمجة تطبيقات Windows، يتم توفير وظيفة مؤشر ترابط عامة في مكتبة C Runtime (من الناحية النظرية يمكن استخدامها في أي نظام تشغيل يدعم سلاسل الرسائل):
unsigned long _beginthread(void (_USERENTRY *__start)(void *), unsigned __stksize, void *__arg);
توفر دلفي أيضًا وظيفة مشابهة بنفس الوظيفة:
وظيفة BeginThread(SecurityAttributes: المؤشر؛ StackSize: LongWord؛ ThreadFunc: TThreadFunc؛ المعلمة: المؤشر؛ CreationFlags: LongWord؛ var ThreadId: LongWord): عدد صحيح؛
وظائف هذه الوظائف الثلاث هي نفسها في الأساس، حيث تقوم جميعها بوضع الكود الموجود في وظيفة الخيط في خيط مستقل للتنفيذ. أكبر فرق بين وظائف الخيط والوظائف العامة هو أنه بمجرد بدء وظيفة الخيط، تعود وظائف بدء الخيط الثلاثة هذه، ويستمر الخيط الرئيسي في التنفيذ إلى الأسفل، بينما يتم تنفيذ وظيفة الخيط في خيط مستقل يستغرق التنفيذ؟ عندما يعود، لا يهتم الخيط الرئيسي ولا يعرف.
في الظروف العادية، بعد عودة وظيفة الخيط، يتم إنهاء الخيط. ولكن هناك طرق أخرى:
واجهة برمجة تطبيقات ويندوز:
VOID ExitThread(DWORD dwExitCode);
مكتبة وقت التشغيل C:
void _endthread(void);
مكتبة وقت تشغيل دلفي:
PROcedure EndThread(ExitCode: Integer);
من أجل تسجيل بعض بيانات مؤشر الترابط الضرورية (الحالة/الخصائص، وما إلى ذلك)، سيقوم نظام التشغيل بإنشاء كائن داخلي لمؤشر الترابط. على سبيل المثال، في نظام التشغيل Windows، المقبض هو مقبض هذا الكائن الداخلي، لذلك يجب تحرير هذا الكائن عندما ينتهي الخيط.
على الرغم من أنه يمكن تنفيذ البرمجة متعددة الخيوط بسهولة باستخدام API أو RTL (مكتبة وقت التشغيل)، إلا أن المعالجة الأكثر تفصيلاً لا تزال مطلوبة لهذا السبب، قامت دلفي بتغليف أفضل للخيوط في وحدة الفئات. هذه هي فئة سلاسل رسائل VCL: TThread
يعد استخدام هذه الفئة أيضًا أمرًا بسيطًا للغاية، حيث تقول معظم كتب دلفي أن الاستخدام الأساسي هو: أولاً قم باشتقاق فئة مؤشر الترابط الخاصة بك من TThread (لأن TThread عبارة عن فئة مجردة ولا يمكنها إنشاء مثيلات)، ثم استخدم طريقة Override Abstract: Execute( This). هي وظيفة مؤشر الترابط، وهي جزء من التعليمات البرمجية التي يتم تنفيذها في مؤشر الترابط). إذا كنت بحاجة إلى استخدام كائن VCL المرئي، فأنت بحاجة إلى القيام بذلك من خلال عملية المزامنة. للحصول على تفاصيل محددة، لن نخوض في التفاصيل هنا، يرجى الرجوع إلى الكتب ذات الصلة.
الشيء التالي الذي ستناقشه هذه المقالة هو كيفية قيام فئة TThread بتغليف سلاسل الرسائل، أي دراسة متعمقة لتطبيق فئة TThread. لأنه فقط من خلال الفهم الحقيقي لها يمكننا استخدامها بشكل أفضل.
ما يلي هو إعلان فئة TThread في DELPHI7 (تناقش هذه المقالة فقط التنفيذ ضمن نظام Windows الأساسي، لذلك تمت إزالة جميع التعليمات البرمجية المتعلقة بمنصة Linux):
TThread = class
خاص
مقبض: مقبض؛
FThreadID: Thandle؛
FCreateSuspending: منطقي؛
تم إنهاؤه: منطقي؛
Fمعلق: منطقي؛
FFreeOnTerminate: منطقية؛
انتهى: منطقي؛
FReturnValue: عدد صحيح؛
FOnTerminate: TNotifyEvent;
FSynchronize: TSynchronizeRecord;
FFatalException: TObject;
الإجراء CallOnTerminate؛
إجراء الفصل Synchronize(ASyncRec: PSynchronizeRecord);
وظيفة GetPriority: TThreadPriority؛
الإجراء SetPriority(Value: TThreadPriority);
الإجراء SetSuspending(Value: Boolean);
محمي
الإجراء CheckThreadError(ErrCode: Integer);
الإجراء CheckThreadError(Success: Boolean overload);
الإجراء DoTerminate الظاهري؛
تنفيذ الإجراء الظاهري؛
مزامنة الإجراء (الطريقة: TThreadMethod)؛
خاصية ReturnValue: عدد صحيح يقرأ FReturnValue يكتب FReturnValue؛
تم إنهاء الخاصية: قراءة منطقية FTerminated؛
عام
إنشاء المنشئ(CreateSuspending: Boolean);
تدمير المدمرة؛
تجاوز الإجراء بعد البناء؛
استئناف الإجراء؛
الإجراء تعليق؛
إنهاء الإجراء؛
وظيفة الانتظار: LongWord؛
إجراء الفصل Synchronize(AThread: TThread; AMethod: TThreadMethod);
إجراء الفصل StaticSynchronize(AThread: TThread; AMethod: TThreadMethod);
الخاصية FatalException: TObject read FFatalException؛
خاصية FreeOnTerminate: قراءة منطقية FFreeOnTerminate، كتابة FFreeOnTerminate؛
مقبض الخاصية: قراءة Thandle FHandle؛
أولوية الخاصية: TThreadPriority قراءة GetPriority كتابة SetPriority؛
الخاصية معلقة: قراءة منطقية FSuspened كتابة SetSuspending؛
الخاصية ThreadID: Thandle read FThreadID؛
خاصية OnTerminate: قراءة TNotifyEvent FOnTerminate وكتابة FOnTerminate؛
نهاية؛
فئة TThread هي فئة بسيطة نسبيًا في لغة دلفي RTL، ولا يوجد عدد كبير من أعضاء الفصل وسمات الفصل بسيطة جدًا وواضحة، ستجري هذه المقالة فقط تحليلًا تفصيليًا لعدد قليل من أساليب أعضاء الفصل الأكثر أهمية والحدث الوحيد: OnTerminate .
(يتبع)