سؤال

أنا أحاول أن أعمل في رأسي أفضل طريقة لتنظيم الكاكاو التطبيق الذي هو بالأساس المتزامنة مدير تحميل.هناك خادم التطبيق محادثات المستخدم يجعل قائمة كبيرة من الأشياء هدم و التطبيق العمليات القائمة.(ليس باستخدام HTTP أو FTP, لذلك أنا لا يمكن استخدام رابط تحميل النظام ؛ سوف يكون الحديث عبر اتصالات مأخذ التوصيل.)

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

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

يبدو أن أتمكن من استخدام NSOperationQueue, و الاتصال setMaxConcurrentOperationCount: مع عدد من الاتصالات.ثم أنا فقط إرم تحميل الطلبات في قائمة الانتظار.ولكن لست متأكدا ، في هذه الحالة ، وكيفية إدارة اتصالات أنفسهم.(مجرد وضعها على كومة ، وتعتمد على قائمة الانتظار لضمان لا أكثر/أقل-تشغيل ؟ رمي في إرسال إشارة جنبا إلى جنب مع كومة؟)

نحن الآن في عالم جديد شجاع Grand Central Dispatch, لا تفتح أي طرق أخرى لمعالجة هذا ؟ للوهلة الأولى لا يبدو أنه منذ GCD الرائد القدرة على توسيع نطاق حيوي التزامن (و ذكر في أبل التوصيات على تغيير المنتج-المستهلك تطبيقات) لا تساعدني.ولكن أنا فقط خدش السطح من القراءة حول هذا الموضوع.

تحرير:

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

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

المحلول 2

من أجل الأجيال القادمة، بعد بعض النقاش في مكان آخر، الحل الذي أعتقد أنني كنت اعتماده في الأساس:

  • لديك قائمة انتظار في عمليات التنزيل المعلقة، فارغة في البداية.
  • لديك مجموعة تحتوي على جميع الاتصالات المفتوحة، فارغة في البداية.
  • لديك مجموعة قابلة للتغيير (قائمة الانتظار، حقا) من اتصالات الخمول المفتوحة، فارغة في البداية.
  • عندما يضيف المستخدم طلب التنزيل:
    • إذا لم تكن صفيف اتصالات الخمول فارغة، فقم بإزالة واحدة وتعيين التنزيل عليه.
    • إذا لم تكن هناك اتصالات خاملة، ولكن عدد الاتصالات الإجمالية لم يصل إلى حد كبير، افتح اتصال جديد، أضفه إلى المجموعة، وتعيين التنزيل عليه.
    • خلاف ذلك، enquue التنزيل لاحقا.
  • عند اكتمال التنزيل: إذا كانت هناك طلبات في قائمة الانتظار، Dequeue One ومنحها للاتصال؛ خلاف ذلك، أضف الاتصال إلى قائمة الخمول.

كل هذا العمل سيعقد على الخيط الرئيسي. سيتم تفريغ عمل فك تشفير نتائج كل تنزيل إلى GCD، لذلك يمكنه التعامل مع اختناق التزامن، ولا يقوم بتسجيل الخيط الرئيسي.

قد يستغرق فتح اتصال جديد بعض الوقت، وبالتالي فإن عملية إنشاء واحدة جديدة قد تكون عبارة عن صبي أكثر تعقيدا في الممارسة الفعلية (على سبيل المثال، encueue "التنزيل"، بدء عملية الاتصال، ثم dequeue عند إنشاء الاتصال بالكامل). لكن ما زلت أعتقد أن تصوري لإمكانية ظروف السباق مبالغ فيها.

نصائح أخرى

إذا كنت تستخدم CFSocket غير حجب المكالمات I/O ، أنا أوافق ، ذلك أن كل ما يحدث على الخيط الرئيسي ، مما يتيح نظام التشغيل التعامل مع مشكلات التوافق منذ كنت مجرد نسخ البيانات و حقا لا تفعل أي حساب.

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

ربما كنت قد تركت شيء مهم ، ولكن على أساس وصف التطبيق I/O bound, لا وحدة المعالجة المركزية ملزمة ، لذلك كل من التزامن الاشياء هو مجرد الذهاب الى جعل أكثر تعقيدا رمز مع الحد الأدنى من التأثير على الأداء.

تفعل كل شيء على الصفحات الرئيسية.

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