![]() |
|
دلفي & threads مفاهيم و تطبيقات . - نسخة قابلة للطباعة +- delphi4arab منتديات دلفي للعرب (https://delphi4arab.net/forum) +-- قسم : منتديات دلفي التقنية (https://delphi4arab.net/forum/forumdisplay.php?fid=6) +--- قسم : دلفي والتعامل مع النظام و الذاكرة (https://delphi4arab.net/forum/forumdisplay.php?fid=20) +--- الموضوع : دلفي & threads مفاهيم و تطبيقات . (/showthread.php?tid=1773) الصفحات:
1
2
|
دلفي & threads مفاهيم و تطبيقات . - TF6M - 11-03-2010 بسم الله الرحمان الرحيم
السلام عليكم و رحمة الله و بركاته
كيف نبرمج تطبيقاتنا بطريقة حديثة ؟ , كيف يمكن لنا أن نسرع من أداء برنامجنا دون وقوع مشاكل أو :frusty: , كيف لنا أن تشغيل عدة عمليات
في آن واحد (ظاهريا) بالتوازي و بشكل متزامن (مدروس) ؟ , ببساطة البرمجة بالإعتماد على آلية Multi_Thread .
بعض التوضيحات "نظريا" :
أنظمة التشغيل تتوافق تماما مع هندسة المعالج و آلياته , الأنظمة الحديثة (Multi_Tache) أساسا تعتمد على تقليص زمن التنفيذ كيف ؟
عن طريق آلية Pipeline, معالج يدعم pipeline ينفذ تعليمات برنامج ما "بالتزامن في طور عمل واحد" وفق روتينا المعالج :
Fetch,decode,memory access,write back لاحظ الجدول التالي الدي يوضح آلية معالجة برنامج بـ Pipeline![]() نفرض مثلا أن لدينا برنامج 20 %تعليمات تحميل و تخزين , 40 %تعليمات منطقية و مقارنة ... , 40 %تعليمات قفز و تفرع ...
لو كان المعالج لا يدعم pipeline سيظطر لتنفيذ تعليمة بعد تعليمة و لن يدخل للتعليمة الجديدة حتى ينهي السابقة ! و إذا كان كل صنف
من التعليمات يحتاج طورين أو أكثر لتنفيذ التعليمة الواحد لك أن تتخيل "مدى بطئ معالجة تعليمات البرنامج المحمل الواحد" لكن مع pipline
أطوار عمل أقل و أداء أسرع يمكن أن ننفذ أكثر من برنامج (Process) بشكل متزامن (Synchronize) بإزاحة توافق (Priority) المخصصة
لكل process على أساس Pid(رقم تعريف البروسس), hProcess(مقبض البروسس), لم أشرح كثيرا فقط صطحيا للدخول في جو الدرس ! ."الان ماذا لو قمنا بنفس عمل نظام التشغيل داخل تطبيقاتنا ؟ يعني أن ننفذ العديد من العمليات بشكل متزامن في آن واحد (ظاهريا) !."
- هناك عشرات التعريفات و المقدمات حول موضوع الـ THread لذا كان علي الدخول من منطلقالشكل العام لإنشاء thread واحد كمثال أول , نعتمد على خصائص البرمجة poo بشكل عادي يعني إنشاء
class مورث من TThread في ديلفي . PHP كود : {$IFDEF VER150}//delphi 7الدي يتيح لنا دمج الدوال و الإجراءات دون مراعات ترتيب الـ implementation (أيضا كإظافة:tong , قمنا بإدراج initialization / finalization يكفي أن نعمل Resume لبدأ تنفيذ Execute الخاص بالـ Thread آليا !. أخر , هدا التطبيق الأول مثال بسيط للمناقشة .... ![]()
. في هذا المثال قمنا ببرمجة عداد بسيط لن تنجح في تنفيذه دون إستعمال الـ threads! , هنا لم يتجمد البرنامج (freeze)
& النتيجة دورية 1/10 ثانية & تحكم أكثر & أداء أحسن (مثلا إستغنينا عن الـ Timer). دلفي & threads مفاهيم و تطبيقات . - mohfa - 11-03-2010 اخي الكريم TF6M بارك الله فيك على هكذا درس . و لكن هناك ملاحظة : لماذا انشئت ال Thread في ال [FONT=Simplified Arabic Fixed]initialization وحررته في ال finalization [FONT=Simplified Arabic Fixed]: كود : [COLOR=#0000bb][FONT=Simplified Arabic Fixed][COLOR=#0000bb]initialization[/COLOR]
[FONT=Simplified Arabic Fixed][COLOR=#0000bb]MyTh[/COLOR][COLOR=#007700]:=[/COLOR][COLOR=#0000bb]MyThread[/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000bb]Create[/COLOR][COLOR=#007700]([/COLOR][COLOR=#0000bb]True[/COLOR][COLOR=#007700][FONT=Simplified Arabic Fixed]);[/COLOR]
[FONT=Simplified Arabic Fixed][COLOR=#0000bb]finalization[/COLOR]
[FONT=Simplified Arabic Fixed][COLOR=#0000bb]MyTh[/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000bb]Free[/COLOR][FONT=Simplified Arabic Fixed][COLOR=#007700];[/COLOR]
[FONT=Simplified Arabic Fixed][COLOR=#0000bb]end[/COLOR][COLOR=#007700]. [/COLOR][/COLOR]ثم صرحت بانشائه في الحدث OnClick للزر : كود : [FONT=Simplified Arabic Fixed][COLOR=#0000bb]procedure TMainFrm[/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000bb]Button1Click[/COLOR][COLOR=#007700]([/COLOR][COLOR=#0000bb]Sender[/COLOR][COLOR=#007700]: [/COLOR][COLOR=#0000bb]TObject[/COLOR][COLOR=#007700][FONT=Simplified Arabic Fixed]);[/COLOR]
[FONT=Simplified Arabic Fixed][COLOR=#0000bb]begin[/COLOR]
[FONT=Simplified Arabic Fixed][COLOR=#0000bb]MyTh[/COLOR][COLOR=#007700]:=[/COLOR][COLOR=#0000bb]MyThread[/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000bb]Create[/COLOR][COLOR=#007700]([/COLOR][COLOR=#0000bb]False[/COLOR][FONT=Simplified Arabic Fixed][COLOR=#007700]);[/COLOR]
[FONT=Simplified Arabic Fixed][COLOR=#0000bb]end[/COLOR][COLOR=#007700];[/COLOR]اقصد ان اقول ان ال Thread قد تم انشاءه مع ال [FONT=Simplified Arabic Fixed]initialization فقط Suspended . [FONT=Simplified Arabic Fixed] دلفي & threads مفاهيم و تطبيقات . - TF6M - 11-03-2010 [FONT=Arial]شكرا بارك الله فيك ,, 1- لن أناقش مسئلة التحرير بل [FONT=Arial]initializationهنا لكي نبدأ بإستعمال الـ Thread مباشرة [FONT=Arial]لا حظ الـ Start غير مفعلة! 2- قمت بإعادة التصريح ببساطة لإعادة العملية , في حالة إيقاف الـ Thread بـ Terminate [FONT=Arial]initialization / [FONT=Arial]finalization عوض إعادة الإنشاء و التحرير في بداية و نهاية عمل الـ Thread ؟ . 3- نعم قمت بإنشاء الـ Thraed كـ [FONT=Simplified Arabic Fixed][FONT=Arial]Suspended [FONT=Arial]فقط لإرجاع أمر بدء تنفيذ [FONT=Arial]Execute [FONT=Arial]لنا (لو كان False لبدأ العد مباشرة بعد التنفيذ) . دلفي & threads مفاهيم و تطبيقات . - mohfa - 11-03-2010 ولكن اخي الكريم TF6M هنا سيحدث Thread Collison في حالة تم الظغط على [FONT=Simplified Arabic Fixed]Button1 لانه سوف يتم انشاء نفس ال Thread يمكن ان يكون باHandle جديد و لكن سوف يتم انشاءى و هذا ماسيحدث خلل في تحريره مرة اخرى لا ال OS لايعرف اي Thread سوف يتم تحريره انطلاقا من ال المقبض او ال HANDLE [FONT=Simplified Arabic Fixed]حاول مثلا عدم استعمال : [FONT=Simplified Arabic Fixed] كود : [COLOR=#0000bb][COLOR=#0000bb]ExitProcess[/COLOR][COLOR=#007700]([/COLOR][COLOR=#0000bb]GetLastError[/COLOR][COLOR=#007700]);[/COLOR][COLOR=#ff8000]//Exit [/COLOR][/COLOR][FONT=Simplified Arabic Fixed] [FONT=Simplified Arabic Fixed]انت انشئت ال Thread مع ال [FONT=Arial]initialization ولكن SUSPENDED ثم انشئته مرة اخرى و لكن في انتظار او Resuming .اذا كان يمكن القيام بكل هذه العمليم هكذا مثلا : [FONT=Arial] كود : procedure TMainFrm.Button1Click(Sender: TObject);
begin
MyTh:=MyThread.Create(False);
//..
//do what ever
//..
//..
MyTh.resume;
end;دلفي & threads مفاهيم و تطبيقات . - kachwahed - 11-03-2010 وعليكم السلام ورحمة الله وبركاته TF6M واليوم الخميس حان وقت درس نفيس ![]() @Mohfa أولا رد السلام ![]() ثانيا: علينا أن نبتعد عن التفاصيل التي لن يفهمها كل من يدخل قسم "دروس دلفي للمبتدئين" لا تنسوا. إقتباس :لماذا انشئت ال Thread في ال initialization وحررته في ال finalizationصح... أنا أيضا ظننت في البداية أنه قام بإنشاء thREad مرتين، وعندما حملت المثال اتضح خلاف ذلك ![]() فالزر Button1 غير مفعل، حتى يتم Terminate للـ Thread. كنت أعددت مثال صغير لتوضيح مفهوم Threads للمبتدئين، وبعد إذن أخي TF6M سأضيف توضيحات. كود : http://i42.tinypic.com/opyeww.jpgالآن، حاول النقر على Exec Thread ثم على ShowMessage مباشرة الفرق واضح ![]() مبدئيا... Thread هي Process يقوم النظام بتشغيلها عوضا عن برنامجك، وبذلك تستفيد من مزايا زيادة السرعة واقتصاد الذاكرة. كل Thread له priority تعني أولوية الـ Thread في النظام (وهذا مهم حالة وجود العديد منها). تنبيه للمبتدئين: حذار الـ Threads ليست للعب! وينبغي التعامل معها بحذر. مثال مرفق. ملاحظة: في نسخة دلفي 2010 تم إضافة الأمر Start. وشكرا على الدرس الرائع وشكرا لتدخلات الأستاذ Mohfa تحياتي. دلفي & threads مفاهيم و تطبيقات . - paix144 - 11-03-2010 السلام عليكم بارك الله فيك أخي TF6M جاء الدرس في الذي أدرس فيه :rtfm2: في المارة القادمة إن أمكن أخي العزيز التعمق أكثر :monster2: أخي كاش واحد لا تنسى درس المؤشرات، أنتظرك دلفي & threads مفاهيم و تطبيقات . - mohfa - 12-03-2010 اولا السلام عليكم و رحمة الله و بركاته . إقتباس :[FONT=Arial]كما قلت لك أعدت إنشاءه فقط في حالة إيقافه يعني لا يمكن أن ننشأه مرتين ولكن ياخي الكريم TF6M اين شرط التاكد من عدمه قبل الانشاء من جديد . ثانيا حتى و لو كنت قد تاكدت من التوقف من الاحسن تحرير ال Thread قبل انشائه مرة جديد يعني استطيع ان استعمل مثلا : كود : if terminated then freeكود : [COLOR=#0000bb]ExitProcess[/COLOR][COLOR=#007700]([/COLOR][COLOR=#0000bb]GetLastError[/COLOR][COLOR=#007700]);[/COLOR][COLOR=#ff8000]//Exit [/COLOR]هكذا تجبر النظام ان يوقف التطبيق مهما كانت النتائج حتى باستعمال GetLastError هنا تقول MS من خلال ال msdn ليس من المستحسن استعمال ال ExitProcess مع ال Threads hاو ال Pip lining لماذا : يمكن ان يكون هناك Infinit او عملية غير منتهية او مايدعى ال Long Process اذا استعملنا ال ExitProcess فهذا سيجبر التطبيق على التوقف مهما كانت النتائج , ومن بين النتائج الخطيرة هي ال System او Memory instability . في حالتك يمكن استعمال ال Waitfor و هذا سوف يجبر ال Thread التحقق من اي Operation غير منتهية او من عدم تفريغ ال Quee وهذا سوف يحرر كل ال Ressources قبل تحرير ال Thread اقول و اعيد انك تقوم بانشاء ال Thread مرتين لماذا تتبع معي ال المشهد : 1* عند بداء التطبيق يتم انشاء ال Thread و لكن Suspended يعني بانتطار اي عملية . 2* عندما اظغط على الزر 2 هذا سوف يقوم بتوقيف ال Thread لزمن معين او Suspended . 3* عندما اظغط على الزر 3 هذا سوف يقوم باعادة تشغيل ال Thread بعدما كان Suspended . 4* عندما اظغط على الزر 4 هذا سوف يقوم بتوقيف ال Thread و انهائه و لكن ليس تحريره يعني ال Handle مازال موجود و ال Ressources مازالت في ال Thread Quee . *5 عندما اظغط على الزر Start ماذا سيحصل ياترى : سوف يتم اعادة انشاء نفس ال Thread و الذي اصلا مازال موجود و لم يتم تحريره . 6* OnCloseQuery : سوف يتم مناداة ال المرحلة 4 و يتم غلق التطبيق . رغم ان ال Thread مازال موجود في الذاكرة اقصد مازال الحيز Reserved . اذا اما ان نستعمل ال : FreeOnTreminate في وقت الانشاء مع : كود : Constructor MyThread.Create;
Begin
Inherited Create(Suspended);//If False = start when we call create constructor !.
_i:= 0;//Initialization ...
End;مع : If terminated then free . او نستعمل ال Waitfor ثم ال free . لان terminate لا تحرر ال Thread بل توقفه عن العمل . انظر هنا مثلا كود : https://forums.codegear.com/message.jspa?messageID=142218اتمنى ان الفكرة وصلت . بارك الله فيك و في اخي kachwahed و كل الاعضاء . و السلام عليكم دلفي & threads مفاهيم و تطبيقات . - TF6M - 12-03-2010 الفكرة كلها تتمحور حول إعادة إنشاء الـ Thread دون التأكد من تحريره ![]() 1- عند غلق البرنامج سيحرر عندالإنهاء , Finalization 2- أقول و أعيد هدا التطبيق الأول , هناك ما يسمى بـ Blocking & Premature Termination و هي تدخل في الأخطاء التي يقع فيها المبرمج التي يمكن تفاديها بـ Method waitfor 3- أيضا سأتتطرق لـ عيوب التزامن Disadvantage Synchronizer في التطبيق . - حل هذه المشكلة فقط بإظافة شرط التحرير عند أمر الإنهاء : PHP كود : Constructor MyThread.Create;بارك الله فيك على الإهتمام & الإفادة , شكرا. دلفي & threads مفاهيم و تطبيقات . - kachwahed - 12-03-2010 في نسخة Delphi 2010 يمكن كتابة إجراء Synchronize كما يلي: PHP كود : Procedure MyThread.Execute;دلفي & threads مفاهيم و تطبيقات . - TF6M - 12-03-2010 بسم الله الرحمان الرحيم
تعريف الـ Thread:
- العديد من البرامج (خاصة الحديثة منها) تعتمد على تقنية الـ MultiThreading , هل من الممكن أن نأكل و نشرب و نجري في آن واحد :whistling:!؟ دون عوائق.
الـ thread عبارة عن برنامج (Sous_Programe) , وحدة تنفيذ مستقلة , تتكرر بشكل غير منتهى (حلقة) الى أن يتم إنهائها (Terminate)
يتم تنفيدها من طرف نظام التشغيل على أساس : رقم التعريف (threadID) , أولوية التنفيذ (thread Priority) , مقبض الثريد (thread Handle) .
كما يمكن تعمل عدة threads في آن واحد في برنامج ما , لتحسين أداء & سرعة تنفيذ البرنامج .
التطبيق الثاني : - برنامج يقوم بقراءة ملف ما Byte By Byte & يعرض بشكل متزامن القيمة المقروؤة & و نسبة القراءة بالنسبة للملف . - نفس التطبيق السابق من حيث الفكرة , لكن بشكل عملي أحسن :thumbs: . ![]() بالتوفيق ,, |