سؤال

لدي موضوع واحد أن يكتب النتائج في قائمة الانتظار.

في موضوع آخر (واجهة المستخدم الرسومية) ، بشكل دوري (في حالة الخمول) فحص إذا كان هناك نتائج في انتظار مثل هذا:

def queue_get_all(q):
    items = []
    while 1:
        try:
            items.append(q.get_nowait())
        except Empty, e:
            break
    return items

هذا هو وسيلة جيدة للقيام بذلك ؟

تحرير:

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

"عالقة" المشكلة تحولت إلى أن تكون لأنني كنت تفعل المعالجة في الخمول معالج الحدث ، دون التأكد من أن هذه الأحداث هي في الواقع ولدت عن طريق الاتصال wx.WakeUpIdle, كما هو موصى به.

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

المحلول

سأكون مندهشا للغاية إذا get_nowait() دعوة تسبب وقفة قبل لا ترد إذا كانت القائمة فارغة.

هل يمكن أن تكون أنت على نشر عدد كبير من (ربما الكبيرة؟) البنود بين الشيكات التي تعني تلقي موضوع يحتوي على كمية كبيرة من البيانات إلى الانسحاب من Queue?قد تتمكن من محاولة الحد من عدد استرداد دفعة واحدة:

def queue_get_all(q):
    items = []
    maxItemsToRetreive = 10
    for numOfItemsRetrieved in range(0, maxItemsToRetreive):
        try:
            if numOfItemsRetrieved == maxItemsToRetreive:
                break
            items.append(q.get_nowait())
        except Empty, e:
            break
    return items

وهذا من شأنه الحد من تلقي موضوع سحب ما يصل إلى 10 وحدات في وقت واحد.

نصائح أخرى

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

from __future__ import with_statement
import threading

class ItemStore(object):
    def __init__(self):
        self.lock = threading.Lock()
        self.items = []

    def add(self, item):
        with self.lock:
            self.items.append(item)

    def getAll(self):
        with self.lock:
            items, self.items = self.items, []
        return items

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

[Edit2] أود أن غاب حقيقة أن كنت الاقتراع طابور من الخمول حلقة من التحديث ، أرى أن المشكلة لا تتعلق الخلاف, لذلك أدناه نهج ليست ذات صلة المشكلة الخاصة بك.تركته في حالة أي شخص يجد عرقلة البديل من هذا المفيدة:

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

class ItemStore(object):
    def __init__(self):
        self.cond = threading.Condition()
        self.items = []

    def add(self, item):
        with self.cond:
            self.items.append(item)
            self.cond.notify() # Wake 1 thread waiting on cond (if any)

    def getAll(self, blocking=False):
        with self.cond:
            # If blocking is true, always return at least 1 item
            while blocking and len(self.items) == 0:
                self.cond.wait()
            items, self.items = self.items, []
        return items

أعتقد أن أسهل طريقة للحصول على جميع العناصر من قائمة الانتظار التالية:

def get_all_queue_result(queue):

    result_list = []
    while not queue.empty():
        result_list.append(queue.get())

    return result_list

أرى أنك تستخدم get_nowait() والتي وفقا الوثائق "عودة[s] عنصر إذا كان أحد تتوفر على الفور, آخر رفع فارغة استثناء"

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

هل هناك سبب لماذا كنت لا تستخدم طريقة الحصول على() بدلا من ذلك ؟ وقد تكون الحالة أن get_nowait() فشل لأن الانتظار هو خدمة وضع() طلب في نفس اللحظة.

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

responseList = []
for items in range(0, q.qsize()):
    responseList.append(q.get_nowait())

أبسط طريقة هي باستخدام قائمة على الفهم:

items = [q.get() for _ in range(q.qsize())]

استخدام range وظيفة عموما مكروها ، ولكن لم أجد طريقة أبسط حتى الآن.

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