سؤال

متى يجب أن لا استخدام ThreadPool في .Net؟

يبدو أن الخيار الأفضل هو استخدام ThreadPool، وفي هذه الحالة، لماذا لا يكون هو الخيار الوحيد؟

ما هي تجاربك حول هذا؟

هل كانت مفيدة؟

المحلول

السبب الوحيد الذي يجعلني لا أستخدم ThreadPool لتعدد مؤشرات الترابط الرخيصة هو إذا كنت بحاجة إلى ...

  1. التفاعل مع الطريقة قيد التشغيل (على سبيل المثال، لقتلها)
  2. تشغيل الكود على أ خيط STA (هذا حدث لي)
  3. أبقِ الخيط حيًا بعد انتهاء طلبي (ThreadPool المواضيع هي المواضيع الخلفية)
  4. في حال كنت بحاجة إلى تغيير أولوية الموضوع.لا يمكننا تغيير أولوية سلاسل الرسائل في ThreadPool والتي تكون عادية بشكل افتراضي.

ملاحظة.: مقالة MSDN "تجمع مؤشرات الترابط المُدار" يحتوي على قسم بعنوان "متى لا تستخدم مؤشرات ترابط تجمع الخيوط", ، مع قائمة متشابهة جدًا ولكنها أكثر اكتمالًا قليلاً من الأسباب المحتملة لعدم استخدام تجمع مؤشرات الترابط.

هناك الكثير من الأسباب التي تجعلك بحاجة إلى تخطي ThreadPool, ، ولكن إذا كنت لا تعرفهم، ثم ThreadPool ينبغي أن تكون جيدة بما فيه الكفاية بالنسبة لك.

بدلا من ذلك، انظر إلى الجديد إطار الامتدادات الموازية, ، والذي يحتوي على بعض الأشياء الرائعة التي قد تناسب احتياجاتك دون الحاجة إلى استخدام ThreadPool.

نصائح أخرى

@ إريك ، يجب أن أتفق مع دين.الخيوط غالية الثمن.لا يمكنك أن تفترض أن برنامجك هو البرنامج الوحيد الذي يعمل.عندما يكون الجميع جشعين بالموارد، تتضاعف المشكلة.

أفضّل إنشاء المواضيع يدويًا والتحكم فيها بنفسي.إنه يحافظ على الكود سهل الفهم للغاية.

هذا جيد عندما يكون ذلك مناسبا.إذا كنت بحاجة إلى مجموعة من سلاسل العمليات، فكل ما فعلته هو جعل التعليمات البرمجية الخاصة بك أكثر تعقيدًا.الآن عليك كتابة التعليمات البرمجية لإدارتها.إذا كنت تستخدم تجمع سلاسل المحادثات للتو، فستحصل على إدارة سلاسل المحادثات بالكامل مجانًا.ومن المرجح جدًا أن يكون تجمع الخيوط الذي توفره اللغة أكثر قوة وكفاءة وأقل أخطاءً من أي شيء تقوم بتدويره بنفسك.

Thread t = new Thread(new ThreadStart(DoSomething));  
t.Start();  
t.Join();  

آمل أن يكون لديك عادةً بعض التعليمات البرمجية الإضافية بينهما Start() و Join().وإلا فإن الخيط الإضافي لا فائدة منه، وأنت تهدر الموارد بلا سبب.

الناس خائفون جدًا من الموارد التي تستخدمها الخيوط.لم يسبق لي أن رأيت إنشاء موضوع وبدءه يستغرق أكثر من مللي ثانية.لا يوجد حد صارم لعدد المواضيع التي يمكنك إنشاؤها.استخدام ذاكرة الوصول العشوائي هو الحد الأدنى.بمجرد أن يكون لديك بضع مئات من سلاسل الرسائل، تصبح وحدة المعالجة المركزية (CPU) مشكلة بسبب مفاتيح التبديل السياقية، لذلك في هذه المرحلة قد ترغب في الحصول على تصميم مميز.

ميلي ثانية هو طويل الوقت على الأجهزة الحديثة.هذه 3 ملايين دورة على جهاز 3 جيجا هرتز.ومرة أخرى، أنت لست الوحيد الذي يقوم بإنشاء المواضيع.تتنافس خيوطك على وحدة المعالجة المركزية جنبًا إلى جنب مع خيوط كل برنامج آخر.إذا كنت لا تستخدم عددًا كبيرًا جدًا من سلاسل الرسائل، وكذلك برنامج آخر، فهذا يعني أنك استخدمت عددًا كبيرًا جدًا من سلاسل الرسائل معًا.

على محمل الجد، لا تجعل الحياة أكثر تعقيدا مما ينبغي.لا تستخدم تجمع مؤشرات الترابط إلا إذا كنت بحاجة إلى شيء محدد جدًا يقدمه.

بالفعل.لا تجعل الحياة أكثر تعقيدا.إذا كان برنامجك يحتاج إلى عدة سلاسل عمليات، فلا تعيد اختراع العجلة.استخدم تجمع الخيوط.لهذا السبب هناك.هل ستقوم بتدوير فئة السلسلة الخاصة بك؟

تكون تجمعات مؤشرات الترابط منطقية عندما يكون لديك مفهوم مؤشرات الترابط العاملة.في أي وقت يمكنك بسهولة تقسيم المعالجة إلى مهام أصغر، يمكن معالجة كل منها بشكل مستقل، فإن مؤشرات الترابط العاملة (وبالتالي تجمع مؤشرات الترابط) تكون منطقية.

لا تكون تجمعات مؤشرات الترابط منطقية عندما تحتاج إلى مؤشر ترابط يؤدي إجراءات مختلفة تمامًا وغير ذات صلة، والتي لا يمكن اعتبارها "مهام"؛على سبيل المثال، موضوع واحد لمعالجة أحداث واجهة المستخدم الرسومية، وآخر لمعالجة الواجهة الخلفية.لا تكون تجمعات مؤشرات الترابط منطقية أيضًا عند معالجة نماذج خط الأنابيب.

في الأساس، إذا كان لديك سلاسل رسائل تبدأ وتعالج مهمة وتنتهي، فمن المحتمل أن يكون تجمع سلاسل المحادثات هو الحل الأمثل.وإلا فإن تجمع مؤشرات الترابط لن يساعد حقًا.

للإجابة المثيرة للجدل، أود أن أضيف أنه من الأفضل عدم استخدام مؤشر ترابط ThreadPool إذا كنت تريد ضمان أن مؤشر الترابط الخاص بك سيبدأ العمل على الفور.الحد الأقصى لعدد سلاسل الرسائل المجمعة الجاري تشغيلها محدود لكل مجال تطبيق، لذلك قد يتعين على جزء عملك الانتظار إذا كانت جميعها مشغولة.يطلق عليه "عنصر عمل المستخدم في قائمة الانتظار" ، بعد كل شيء.

تحذيران بالطبع:

  1. يمكنك تغيير الحد الأقصى لعدد سلاسل الرسائل المجمعة في التعليمات البرمجية، في وقت التشغيل، لذلك لا يوجد ما يمنعك من التحقق من العدد الحالي مقابل الحد الأقصى وزيادة الحد الأقصى إذا لزم الأمر.
  2. إن تدوير خيط جديد يأتي مع عقوبة زمنية خاصة به - سواء كان من المفيد بالنسبة لك أن تتلقى الضربة أم لا يعتمد على ظروفك.

أنا لا أتحدث كشخص لديه المعرفة النظرية فقط هنا.أنا أكتب وأحافظ على تطبيقات الحجم الكبير التي تستفيد بشكل كبير من عمليات القراءة المتعددة ، وأنا عمومًا لا أجد أن تجمع الخيوط هو الإجابة الصحيحة.

آه، حجة من السلطة - ولكن كن دائمًا على دراية بالأشخاص الذين قد يكونون في فريق Windows kernel.

لم يكن أي منا يجادل في حقيقة أنه إذا كانت لديك بعض المتطلبات المحددة، فقد لا يكون .NET ThreadPool هو الشيء الصحيح.ما نعترض عليه هو التقليل من تكاليف آلة إنشاء الخيط.

التكلفة الكبيرة لإنشاء سلسلة رسائل هي سبب وجود ThreadPool في المقام الأول.لا أريد أن تمتلئ أجهزتي بأكواد مكتوبة من قبل أشخاص تم تضليلهم بشأن تكلفة إنشاء سلسلة رسائل، ولا يعرفون، على سبيل المثال، أن ذلك يتسبب في استدعاء طريقة في كل ملف DLL واحد وهو مرفقة بالعملية (بعضها سيتم إنشاؤه بواسطة جهات خارجية)، والتي قد تؤدي إلى زيادة كمية كبيرة من التعليمات البرمجية التي لا يلزم أن تكون في ذاكرة الوصول العشوائي (RAM) على الإطلاق ومن المؤكد أنها لا تحتاج إلى أن تكون في L1.

إن شكل التسلسل الهرمي للذاكرة في الآلة الحديثة يعني أن "تشتيت انتباه" وحدة المعالجة المركزية هو أسوأ شيء يمكنك القيام به، ويجب على كل من يهتم بمهنته أن يعمل بجد لتجنب ذلك.

عندما تنوي تنفيذ عملية ستستغرق وقتًا طويلاً، أو ربما سلسلة محادثات مستمرة في الخلفية.أعتقد أنه يمكنك دائمًا زيادة عدد سلاسل الرسائل المتوفرة في المجموعة ولكن لن يكون هناك أي فائدة في تكبد تكاليف إدارة سلسلة المحادثات التي لن يتم إعادتها أبدًا إلى المجموعة.

لدى MSDN قائمة ببعض الأسباب هنا:

http://msdn.microsoft.com/en-us/library/0ka9477y.aspx

هناك العديد من السيناريوهات التي يكون من المناسب فيها إنشاء وإدارة مؤشرات الترابط الخاصة بك بدلاً من استخدام مؤشرات ترابط تجمع مؤشرات الترابط:

  • أنت بحاجة إلى موضوع المقدمة.
  • أنت تحتاج إلى أن يكون لمؤشر الترابط أولوية معينة.
  • لديك مهام تؤدي إلى حظر مؤشر الترابط لفترات طويلة من الزمن.يحتوي تجمع الخيوط على عدد أقصى من المواضيع ، لذلك قد يمنع عدد كبير من مؤشرات ترابط تجمع الخيوط المحظورة المهام من البداية.
  • تحتاج إلى وضع المواضيع في شقة ذات ترابط واحد.كافة مؤشرات الترابط ThreadPool موجودة في الشقة متعددة مؤشرات الترابط.
  • يجب أن يكون لديك هوية ثابتة مرتبطة بسلسلة الرسائل، أو لتخصيص سلسلة رسائل لمهمة ما.

تعتبر سلاسل Threadpool مناسبة للمهام التي تستوفي المعايير التالية:

  1. لن تضطر المهمة إلى قضاء أي وقت كبير في انتظار حدوث شيء ما
  2. أي شيء ينتظر انتهاء المهمة من المرجح أن ينتظر انتهاء العديد من المهام، لذا فإن أولوية جدولته ليست عرضة للتأثير على الأشياء كثيرًا.

سيؤدي استخدام مؤشر ترابط Threadpool بدلاً من إنشاء مؤشر ترابط جديد إلى توفير قدر كبير ولكن محدود من الوقت.إذا كان هذا الوقت كبيرًا مقارنة بالوقت الذي سيستغرقه تنفيذ مهمة ما، فمن المحتمل أن تكون مهمة Threadpool مناسبة.ومع ذلك، كلما زاد الوقت اللازم لتنفيذ مهمة ما، قلت فائدة استخدام مجموعة مؤشرات الترابط وزادت احتمالية إعاقة المهمة لكفاءة مجموعة مؤشرات الترابط.

@ اريك

@ ديريك، أنا لا أتفق تمامًا مع السيناريو الذي تستخدمه كمثال.إذا كنت لا تعرف بالضبط ما الذي يتم تشغيله على جهازك وعدد الخيوط الإجمالية، والمقابض، ووقت وحدة المعالجة المركزية، وذاكرة الوصول العشوائي، وما إلى ذلك، التي سيستخدمها تطبيقك تحت قدر معين من التحميل، فأنت في مشكلة.

هل أنت العميل المستهدف الوحيد للبرامج التي تكتبها؟إذا لم يكن الأمر كذلك، فلا يمكنك التأكد من معظم ذلك.ليس لديك عمومًا أي فكرة عندما تكتب برنامجًا ما إذا كان سيتم تنفيذه بشكل فعال منفردًا، أو ما إذا كان سيتم تشغيله على خادم ويب يتعرض لهجوم DDOS.لا يمكنك معرفة مقدار وقت وحدة المعالجة المركزية الذي ستحصل عليه.

بافتراض أن سلوك برنامجك يتغير بناءً على الإدخال، فمن النادر أن تعرف بالضبط مقدار الذاكرة أو وقت وحدة المعالجة المركزية الذي سيستهلكه برنامجك.بالتأكيد، يجب أن تكون لديك فكرة جيدة عن كيفية عمل برنامجك، لكن معظم البرامج لا يتم تحليلها مطلقًا لتحديد مقدار الذاكرة بالضبط، وعدد المقابض، وما إلى ذلك.سيتم استخدامها، لأن التحليل الكامل مكلف.إذا كنت لا تكتب برامج في الوقت الفعلي، فإن المردود لا يستحق كل هذا الجهد.

بشكل عام، يعد الادعاء بمعرفة كيفية تصرف برنامجك بالضبط أمرًا بعيد المنال، أما الادعاء بمعرفة كل شيء عن الآلة فهو أمر مثير للسخرية.

ولكي نكون صادقين، إذا كنت لا تعرف بالضبط ما هي الطريقة التي يجب عليك استخدامها:الخيوط اليدوية، وتجمع الخيوط، والمندوبين، وكيفية تنفيذها للقيام بما يحتاجه تطبيقك فقط، أنت في ورطة.

أنا لا أختلف تماما، ولكن لا أرى حقا مدى صلة ذلك.هذا الموقع موجود هنا على وجه التحديد لأن المبرمجين لا يملكون دائمًا جميع الإجابات.

إذا كان تطبيقك معقدًا بما يكفي ليتطلب تقليل عدد سلاسل العمليات التي تستخدمها، ألا تريد دائمًا تحكمًا أكبر مما يوفره لك إطار العمل؟

لا.إذا كنت بحاجة إلى مجموعة مؤشرات الترابط، فسوف أستخدم المجموعة المتوفرة، ما لم وإلى أن أجد أنها غير كافية.لن أفترض ببساطة أن تجمع مؤشرات الترابط المقدم غير كافٍ لاحتياجاتي دون التأكد من ذلك.

أنا لا أتحدث كشخص لديه المعرفة النظرية فقط هنا.أنا أكتب وأحافظ على تطبيقات كبيرة الحجم تستخدم تعدد مؤشرات الترابط بشكل مكثف، ولا أجد بشكل عام أن تجمع مؤشرات الترابط هو الإجابة الصحيحة.

كانت معظم خبرتي المهنية مع برامج المعالجة المتعددة وتعدد العمليات.لقد كنت بحاجة في كثير من الأحيان إلى طرح الحل الخاص بي أيضًا.هذا لا يعني أن تجمع مؤشرات الترابط ليس مفيدًا أو مناسبًا في كثير من الحالات.تم إنشاء تجمع مؤشرات الترابط للتعامل مع مؤشرات الترابط العاملة.في الحالات التي تكون فيها مؤشرات الترابط العاملة المتعددة مناسبة، يجب أن يكون تجمع مؤشرات الترابط المقدم بشكل عام هو النهج الأول.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top