كيف يمكنني الحصول على مأخذ عدم عرقلة الاتصال () الصورة؟

StackOverflow https://stackoverflow.com/questions/1205863

سؤال

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

وبسبب ذلك، اخترت للعمل مع مآخذ متزامنة، بدلا من البريد الالكتروني غير المرغوب المواضيع. الآن لدي مشكلة صغيرة:

والاشياء المتزامن يعمل مثل السحر، ولكن عندما أقوم بتوصيل إلى 100 المضيفين، وأحصل على 100 مهلة (مهلة = 10 ثانية) ثم انتظر 1000 ثانية، فقط لمعرفة فشلت كل ما عندي من الاتصالات.

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

وتخفيض المهلة ليس حلا مقبولا.

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

هل أنا حقا بحاجة إلى استخدام المواضيع؟

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

المحلول

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

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

وكمثال على ذلك، الأعمال التالية على جميع أنظمة لينكس بلدي

import asyncore, socket

class client(asyncore.dispatcher):
    def __init__(self, host):
        self.host = host
        asyncore.dispatcher.__init__(self)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.connect((host, 22))

    def handle_connect(self):
        print 'Connected to', self.host

    def handle_close(self):
        self.close()

    def handle_write(self):
        self.send('')

    def handle_read(self):
        print ' ', self.recv(1024)

clients = []
for i in range(50, 100):
    clients.append(client('cluster%d' % i))

asyncore.loop()

وأين في cluster50 - cluster100، هناك العديد من الأجهزة التي لا تستجيب، أو غير موجودة. هذا الطباعة يبدأ على الفور:

Connected to cluster50
  SSH-2.0-OpenSSH_4.3

Connected to cluster51
  SSH-2.0-OpenSSH_4.3

Connected to cluster52
  SSH-2.0-OpenSSH_4.3

Connected to cluster60
  SSH-2.0-OpenSSH_4.3

Connected to cluster61
  SSH-2.0-OpenSSH_4.3

...

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

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

نصائح أخرى

واستخدم select حدة. هذا يسمح لك أن تنتظر اكتمال I / O على مآخذ غير مؤمن متعددة. وهنا rel="noreferrer"> حول اختر. من لهم صلة إلى الصفحة:

<اقتباس فقرة>   

في C، الترميز select معقد إلى حد ما.   في بيثون، انها قطعة من الكعكة، ولكن   انها قريبة بما فيه الكفاية إلى الإصدار C   أنه إذا فهم حدد في   بيثون، سيكون لديك صعوبة تذكر   مع أنه في C.

ready_to_read, ready_to_write, in_error = select.select(
                  potential_readers, 
                  potential_writers, 
                  potential_errs, 
                  timeout)
<اقتباس فقرة>   

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

     

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

     

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

     

إذا كان لديك "الخادم" مأخذ، ووضعها   في قائمة potential_readers. لو أنه   يخرج في القائمة قابلة للقراءة، بك   استعرض إرادة (شبه المؤكد) العمل.   إذا قمت بإنشاء مأخذ جديد ل   اتصال لشخص آخر، ووضعها في   قائمة potential_writers. إذا كان يظهر   في القائمة للكتابة، لديك   فرصة لائقة أنها مرتبطة.

استخدم الملتوية .

ووهو محرك غير متزامن الشبكات مكتوبة في بيثون، ودعم بروتوكولات عديدة، ويمكنك إضافة الخاصة بك. ويمكن استخدامه لتطوير ومراكز خدمة العملاء. ولكنه لا يمنع على اتصال.

هل نظرتم الى asyncore وحدة؟ قد يكون مجرد ما تحتاجه.

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