من مشکل شما و ایشون رو متوجه نشدم تا بتونم جواب مرتبطی بدم که به دردتون بخوره، تا اونجایی که من فهمیدم آقا/خانم Delphi-7 میخواست یکمی بیشتر در مورد multi-threading بدونه و بقول خودشون "در لینکهایی که دوستان گزاشتند خیلی توجه کردم" ولی به نتیجه نرسیده بودن؛ پست های بنده در مورد کلیات برنامه های چند نخی و ساده ترین مثالی که به ذهنم رسید (و پیشبرد اون) بود؛ به هر صورت اگه قصدتون ادامه این تاپیک هست، با اجازه دوستان، یکمی ریزتر میشیم ...
بنده بالشخصه، صادقانه بگم که شروع برنامه نویسی چندنخی برام با دلفی شروع نشد و بیشتر با سی++ و BCB6 درگیر بودم (یعنی "باید" داشت!)، و همونطوریکه جناب کشاورز گفتن من مجبور بودم با الگوریتمهای موازی کار کنم و انواع روشهای این کار رو بررسی کردم...
یعنی برنامه ام (حداقل) باید به 60 تا کانال همزمان قابلیت پاسخگویی میداشت، به نظر شما چه راهی میرسه؟ روی هر کانال عملیات مجزا و مستقل از هم انجام میشه و مجبوریم از طرف دیگه به Thread اصلی بگیم که هر کدوم از کانال هامون (Thread هامون) در چه وضعیتی بسر میبرن؟ چه اتفاقاتی (شامل چندین نوع عملیات مختلف) الان داره تو کانال موردنظر اتفاق میافته؟ هر جا لازمه واسه کانال و Thread موردنظر چیزی فرستاد و ...
از طرف دیگه بخاطر درگیری با سخت افزار مجبور بودیم سختی کار (بحث اش خیلی مفصله ...) با تردینگ سی رو به جون بخریم، بتدریج که تجربه مون بیشتر شد، وابستگی به سخت افزار منتفی شد و تونستیم بریم رو دلفی. اونوقته که شما قدر کلاس TThread رو می فهمید و سادگی و قابلیت اطمینان اش رو متوجه میشید ...
================================================== ===================
روشهایی که برای Synchronization استفاده میشن برای اینه که در متدهایی که مطمئن نیستید Thread-Safe هستند یا نه، در استفاده از منابع مشابه conflict پیش نیاد، مثلاً تو مثال ما (پست های قبلی بنده در این تاپیک)، این منابع مشترک اشیاء موجود رو فرم اصلی (یا فرمهای دیگه) هست و روشی که برای اینکار تو اونجا استفاده شده بود پروسیجر Synchronize هست.
حالا اگه نیاز دارید که به اشیاء (یا نمونه های کلاس) خاصی، روی فرم دسترسی همزمان داشته باشید از این پروسیجر و سایر روش ها، کلاس ها یا متدهای مرتبط مثل CheckSynchronize، TCriticalSection، TMultiReadExclusiveWriteSynchronizer و ... استفاده می کنید، اگه کار دیگه ای میخواهید بکنید باید راه حل مرتبط با اون رو پیاده سازی کنید! من کی گفتم برای بالا رفتن سرعت (یا هر منظور دیگه ای که شما دارید و من نمیدونم چیه!) برنامه باید از Synchronize استفاده بکنه؟ هیچ ربطی نداره ...
شما دقیقاً باید بدونید که چی میخواهید، بعد برید سراغ Thread؛ برای برنامه نویسانی که دارن فقط رو رابط کاربری یا موارد مشابه کار میکنن، نیازی نیست برن دنبال Thread، برای اینکه بقول دوستمون خود Threadها هم نیاز به resource دارن و استفاده بیجا از اونها بیشتر سربار هست تا مفید فایده بودن؛ بنابراین استفاده از Threadها مثلاً برای بالا رفتن سرعت برنامه و بهینه شدن و ... کاملاً اشتباهه، چون در حقیقت هر Thread به همون اندازه Thread اصلی شما، منابع سیستم رو اشغال میکنه (هرچقدر هم که کم باشه)، اینطوری نیست که من حال میکنم تو اینکار از Thread استفاده کنم چون حالا دیگه بلدم از Thread استفاده کنم و ... بعبارت دیگه هر Thread به " time slice" مجزا تو CPU ایجاد میکنه، و مجبورش میکنه که task بیشتری رو پردازش کنه، پس تو امور معمولی Thread بیشتر باعث کاهش سرعت میشه تا افزایش سرعت!
مواردی که مثلاً استفاده از Thread می تونه مفید باشه :
- پروژه شما طوری هست که مجبورید از الگوریتم های موازی استفاده کنید، مثلاً همون موردی که من چند سطر قبل عرض کردم، اکثر سیستم های مخابراتی اینطورین، یعنی شما راه فرار ندارین و البته که مدیریت Thread ها هم خیلی مهمه، چون هر لحظه (بصورت همزمان) تعداد زیادی از مشترکین دارن با سیستم شما کار میکنن و اگه قرار باشه از هر Thread یه آشغال رو سیستم بمونه یا منابعی آزاد نشه یه روز هم نمی کشه که کل Virtual Memory ویندوز پر میشه یا اصلاً برنامه تون منفجر میشه!
- برنامه شما یه پردازش خیلی بزرگ رو مدیریت میکنه مثلاً کوئری های حجیم بانک اطلاعاتی یا محاسبات پیچیده زمان بر، که چندین دقیقه زمان می برن؛ تو اینحالت (تو برنامه هایWin-16 یا Win-32) رابط کاربری شما قفل میکنه یا بعبارت دیگه فریز میشه! ایجاد Thread های مجزا برای اینکار باعث میشه که پردازش موردنظر بره پشت صحنه و رابط کاربری شما آزاد بشه.
- مطمئنید که برنامه شما از یه سیستم چند-پردازنده بهره میبره. برای مثال، Windows NT قابلیت کار با سیستم های SMP رو داره. با برنامه های Multi-Thread روی چنین سیستم هایی (هم سخت افزار و هم نرم افزار) شما مطمئن میشید که Thread های مجزا روی پردازنده های مجزا اجرا میشن و شما می تونید از تعادل و کارآیی بهینه روی پردازنده های سیستم بهره من بشید.
- هیچ کدوم از شرایط بالا صادق نیست و شما از یک سیستم تک پردازنده و سیستم عامل معمولی استفاده می کنید ولی یه کار حجیم دارید تو برنامه تون انجام میدین که باید کاربر هم ببینه، مثلاً تو نمایش فرمتون هزار و صد تا کامپوننت و اسکین های خفن لود می کنید! بگذریم که کارتون ورسته یا نه، ولی شما تصمیمتو گرفتی و CPU بیچاره باید تمام این چیزهای "خوشگل" رو تو پردازش های در حد صفر و یک و الگوریتم های فوق پیچیده انجام بده، تجربه نشون داده که شکوندن الگوریتم سمت برنامه شما به راه حل های کوچک تر و انجام مستقل اونها، cycle های کمتری از CPU می گیره، حالا این وظیفه شماست و بقول آقای کشاورز، ازتون میخوان که : "راه حلی ارائه کنید که بشه اولا آن کار را به بخش های کوچکتری تقسیم کرد، و ثانیا آن بخش های کوچکتر را بطور مستقل از هم اجرا کرد." هروقت دقیقاً این مفهوم رو درک کردید و تونستید الگوریتم های Boxing رو تو بارگیری اجزاء فرم پیاده کنید با تقسیم قطعات کوچکتر برنامه بین Thread های مجزا کارآیی سیستم بطور قابل ملاحظه ای تغییر می کند (اگه تا اون موقع هنوز اصرار به این نوع برنامه نویسی داشته باشید!)
دارم میرم، امیدوارم بحث رو با هم ادامه بدیم ...!)
http://www.delphicorner.f9.co.uk/articles/op4.htm
http://www.delphicorner.f9.co.uk/articles/db1.htm