c++ - الآلاف من القارئ/الكاتب أقفال في عملية واحدة




synchronization cross-platform (2)

أنا حاليا تصميم C ++ عبر منصة (لينكس / ويندوز) تطبيق الخادم مع نمط تزامن على نطاق واسع. أنا داخليا استخدام دفعة :: موضوع كتجريد من المواضيع أوس محددة. مشكلتي هي حماية مجموعة من البيانات، كل عنصر من صفيف يتم حمايتها من قبل القارئ مستقلة / الكاتب القفل .

يحتوي صفيفتي على 4096 عنصر . وبالنظر إلى حل مشكلة "القراء ذات األولوية للقراء - الكتاب" التي يتم تقديمها في " الكتاب الصغير من سيمافوريس ") صفحة 85 (، فإن تطبيقي يحتاج إلى 5 سيمافوريس لكل عنصر صفيف. وهذا يعطي ما مجموعه حوالي 20000 سيمافوريس (أو، على قدم المساواة، 20000 موتكسس + 20000 متغيرات الشرط).

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

سؤالي عبارة عن قسمين:

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

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

شكرا مقدما!

ملخص الإجابات حتى الآن

  1. لا ينصح باستخدام الآلاف من سيمافوريس، وخاصة من منظور عبر منصة. وهكذا، حتى لو لم تكن سيمبوريس إنتيربروسيس (أنها لا تزال تستهلك مقابض تحت ويندوز).
  2. وهناك طريقة مباشرة لحل مشكلتي هي تقسيم صفيف بلدي على سبيل المثال 64 الرهانات من 16 عنصرا، وربط كل من هذه الرهانات مع قفل واحد القراءة / الكتابة . لسوء الحظ، وهذا يدخل الكثير من الخلاف (1 الكاتب سوف يمنع يقرأ إلى 15 عناصر).
  3. حفر إلى تعزيز شفرة المصدر، لقد وجدت أن:

    • تنفيذ "دفعة :: موتكس" لا التفاف CRITICAL_SECTION الكائنات تحت ويندوز (ولكن كريتيفنت و ريادوريتباريير)،
    • "بوست :: shared_mutex" يستخدم كراتيسيمافور ضمن ويندوز (التي هي وزن ثقيل، كائنات إنتيربروسيس)، و
    • "بوست :: shared_mutex" لا يقوم بالتفاف "pthread_rwlock_t" تحت لينوكس.

    ولا تبدو أسباب ذلك واضحة بالنسبة لي. على وجه الخصوص، واستخدام الكائنات إنتيربروسيس ل "دفعة :: common_mutex" تحت ويندوز يبدو دون المستوى الأمثل بالنسبة لي.

ملخص الأسئلة المفتوحة حتى الآن

  1. كيف يمكنني إنشاء مجموعة من N "محاكاة سيمافوريس" في الجزء العلوي من 1 سيمافور الفعلي، والحفاظ على التنافس بين سيمافوريس المحاكاة صغيرة قدر الإمكان؟
  2. كيف "بوست :: موتكس" و "بوست :: common_mutex" مقارنة مع نظرائهم الأصلي (CRITICAL_SECTION و pthread_rwlock_t)؟

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

  2. تقسيم عناصر 4096 الخاص بك إلى 30 (على سبيل المثال) مجموعات من 140 عناصر وتعيين لكل 140 مجموعة إشارة واحدة. ثم 30 (في هذا المثال) ستحاول سلاسل الترابط الوصول إلى تلك المجموعات 30 وسيتم الحصول على سينكرونيزد استنادا إلى كل 140-مجموعة-سيمافور.


سأخبرك بما أفكر به من منظور ويندوز. أنا من ذوي الخبرة جدا في كتابة تطبيقات خادم ويندوز.

أولا، هناك على الإطلاق أي مشكلة لإنشاء 20K سيمافوريس لعملية واحدة. انها كائن خفيف الوزن جدا. حتى "بين العملية" سيمافوريس.

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

بحيث قد تجد نفسك الوضع حيث معظم الوقت المعالج ينفق في مجرد استدعاء أساليب التزامن.

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

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

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







semaphore