سؤال

حاليا، لدي عدد كبير من حساب C # (مكالمات الأسلوب) المقيمين في قائمة انتظار سيتم تشغيلها بالتتابع. سيستخدم كل حساب بعض خدمة الكمون العالية (الشبكة أو القرص ...).

كنت أستخدم Mono Coroutines للسماح بالحساب التالي في قائمة انتظار الحساب للمتابعة أثناء انتظار الحساب السابق خدمة الزمن العالية للعودة. ومع ذلك، أفضل عدم اعتماد على أحادي التوابل.

هل هناك نمط تصميم قابل للتنفيذ في C # من سيمكنني من معالجة حسابات إضافية أثناء انتظار إعادة خدمات الزمن العالية؟

شكرا

تحديث:

أحتاج إلى تنفيذ عدد كبير (> 10000) من المهام، وستكون كل مهمة تستخدم بعض الخدمات عالية الكمون. على Windows، لا يمكنك إنشاء الكثير من المواضيع.

تحديث:

في الأساس، أحتاج إلى نمط تصميم يحاكي المزايا (على النحو التالي) من المهام في الثعبان الزائد (http://www.stackless.com/)

  1. ضخمة # من المهام
  2. إذا كتل المهمة المهمة التالية في قائمة الانتظار تنفذ
  3. لا دورة وحدة المعالجة المركزية الضائعة
  4. الحد الأدنى من التبديل العلوي بين المهام
هل كانت مفيدة؟

المحلول

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

النظر في طريقة

IEnumerable Thread ()
{
    //do some stuff
    Foo ();

    //co-operatively yield
    yield null;

    //do some more stuff
    Bar ();

    //sleep 2 seconds
    yield new TimeSpan (2000);
}

سوف يقوم برنامج التحويل البرمجي C # بفك هذا في آلة الحالة - ولكن المظهر هو أنه من مجثر التعاونية.

النمط واضح تماما. يمكنك تنفيذ "جدولة" تحافظ على قائمة بجميع أجهزة ienumerators النشطة. نظرا لأنها دورات من خلال القائمة، فإنه "يعمل" كل واحد باستخدام movenext (). إذا كانت قيمة MoveNext FALSE، فقد انتهت الموضوع، وسيتم إزالته المجدول من القائمة. إذا كان هذا صحيحا، فإن المجدول يصل إلى العقار الحالي لتحديد الحالة الحالية للخيط. إذا كان ذلك من جديد، فإن الخيط يرغب في النوم، وانتقله المجدول إلى بعض قائمة الانتظار التي يمكن مسحها مرة أخرى في القائمة الرئيسية التي انتهت فيها مواعدي النوم.

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

لقد قمت بتنفيذ بسيط لهذا المجدول في حوالي 150Loc لكنني لم أحصل على جولة لتدوين الرمز بعد. كان لدينا غلاف Phyresharp Phyreengine (الذي لن يكون عاما)، حيث يبدو أنه يعمل بشكل جيد للغاية للتحكم في بضع مئات من الأحرف في أحد عروضنا. اقترضنا المفهوم من محرك Unity3D - لديهم بعض المستندات عبر الإنترنت شرحها من وجهة نظر المستخدم.

نصائح أخرى

أود أن أوصي باستخدام تجمع موضوع لتنفيذ مهام متعددة من قائمة انتظارك مرة واحدة في دفعات يمكن التحكم فيها باستخدام قائمة بالمهام النشطة التي تغذي قائمة انتظار المهام.

في هذا السيناريو، سيكون مؤشر ترابط العامل الرئيسي الخاص بك مبدئيا المهام n من قائمة الانتظار في قائمة المهام النشطة المراد إرسالها إلى تجمع الخيط (على الأرجح باستخدام QueueUserworkitem.)، حيث يمثل N مبلغ قابل للإدارة لن يقوم بتحميل تجمع مؤشر الترابط، يقوم بتسجيل التطبيق الخاص بك بتكاليف جدولة الخيط وتكاليف المزامنة، أو تمتص الذاكرة المتوفرة نظرا لذاكرة I / O مجتمعة من كل مهمة.

كلما اكتمال إشارات المهام إلى مؤشر ترابط العمال، يمكنك إزالته من قائمة المهام النشطة وإضافة واحدة التالية من قائمة انتظار المهام المراد تنفيذها.

سيتيح لك ذلك الحصول على مجموعة متداول من المهام N من قائمة انتظارك. يمكنك التلاعب N بالتأثير على خصائص الأداء والعثور على أفضل ما هو الأفضل في ظروفك الخاصة.

نظرا لأنك تقوم في نهاية المطاف بضغوط بواسطة عمليات الأجهزة (القرص I / O والشبكة I / O، CPU) أتصور أصغر أفضل. اثنين من مهام تجمع الموضوعات تعمل على القرص I / O على الأرجح لن تنفذ أسرع من واحد.

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

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

آمل أن هذا منطقي!

ملاحظة: هل لديك أي اعتماد على ترتيب المهام؟

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

أليس هذا الاستخدام التقليدي للمعالجة متعددة الخيوط؟

إلقاء نظرة على أنماط مثل المفاعل هنا

كتابةها لاستخدامها async io. قد تكون كافية.

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

يجب أن نلقي نظرة على هذا:

http://www.replicator.org/node/80.

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

بعض المعلومات الأخرى حول النمط "التفاعلي" (كما ذكر عن طريق ملصق آخر) فيما يتعلق بالتنفيذ في .NET؛ المعروف أيضا باسم "LINQ إلى الأحداث"

http://themechanicalbride.blogspot.com/2009/07/introducing-rx-linq-to-events.html.

-

في الواقع، إذا كنت تستخدم مؤشر ترابط واحد لمهمة، فسوف تفقد اللعبة. فكر في السبب في أن node.js يمكن أن يدعم عددا كبيرا من التصنيفات. باستخدام عدد قليل من الموضوعات مع ASYNC IO !!! وظائف ASYNC والانتظار يمكن أن تساعد في ذلك.

foreach (var task in tasks)
{
    await SendAsync(task.value);
    ReadAsync(); 
}

SendAync () و Readasync () هي وظائف مزيفة لاستدعاء ASYNC IO.

التوازي المهمة هو أيضا اختيار جيد. لكنني لست متأكدا من أحد أسرع. يمكنك اختبار كل منهما في قضيتك.

نعم بالطبع يمكنك ذالك. تحتاج فقط إلى إنشاء آلية المرسل التي ستدعو إلى Lambda تقدمها وتذهب إلى قائمة انتظار. يستخدم كل الكود الذي أكتبه في الوحدة هذا النهج وأستطيع استخدام Coroutines أبدا. أنا التفاف الأساليب التي تستخدم coroutines مثل www الاشياء فقط للتخلص منه. من الناحية النظرية، يمكن أن تكون Coloutines أسرع لأن هناك أقل في النفقات العامة. عمليا، يعرضون بناء جملة جديد إلى لغة للقيام بمهمة تافهة إلى حد ما، وعلاوة على ذلك، لا يمكنك اتباع تتبع المكدس بشكل صحيح في خطأ في روتين مشترك لأن كل ما تراه هو -> التالي. سيكون عليك بعد ذلك تنفيذ القدرة على تشغيل المهام في قائمة الانتظار على مؤشر ترابط آخر. ومع ذلك، هناك وظائف متوازية في أحدث .NET وسوف تكتب أساسا وظيفة مماثلة. لن يكون العديد من خطوط التعليمات البرمجية حقا.

إذا كان أي شخص مهتما، فسأرسل الرمز، فلا تملكه لي.

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