سؤال

لدي مؤشر ترابط يقوم بإلحاق صفوف بـ self.output وحلقة يتم تشغيلها حتى يصبح self.done صحيحًا (أو يتم الوصول إلى الحد الأقصى لوقت التنفيذ).

هل هناك طريقة أكثر فعالية للقيام بذلك بخلاف استخدام حلقة while التي تتحقق باستمرار لمعرفة ما إذا تم ذلك أم لا.تؤدي الحلقة أثناء التشغيل إلى ارتفاع وحدة المعالجة المركزية إلى 100% أثناء تشغيلها.

time.clock()
while True:

    if len(self.output):
        yield self.output.pop(0)

    elif self.done or 15 < time.clock():
        if 15 < time.clock():
            yield "Maximum Execution Time Exceeded %s seconds" % time.clock()
        break
هل كانت مفيدة؟

المحلول

هل تلحق سلاسل الرسائل الخاصة بك بـ self.output هنا، حيث تستهلكها مهمتك الرئيسية؟إذا كان الأمر كذلك، فهذه مهمة مصممة خصيصًا له قائمة الانتظار.قائمة الانتظار.يجب أن يصبح الكود الخاص بك شيئًا مثل:

import Queue

# Initialise queue as:
queue = Queue.Queue()
Finished = object()   # Unique marker the producer will put in the queue when finished

# Consumer:
try:
    while True:
        next_item = self.queue.get(timeout=15)
        if next_item is Finished: break
        yield next_item

except Queue.Empty:
    print "Timeout exceeded"

تضيف سلاسل المنتج الخاصة بك عناصر إلى قائمة الانتظار باستخدام queue.put(item)

[يحرر] يحتوي الكود الأصلي على مشكلة تعارض عند التحقق من self.done (على سبيل المثال، قد يتم إلحاق عناصر متعددة بقائمة الانتظار قبل تعيين العلامة، مما يتسبب في إنقاذ الكود عند العنصر الأول).تم التحديث باقتراح من ΤΖΩΤΖΙΟΥ - يجب أن يقوم مؤشر ترابط المنتج بدلاً من ذلك بإلحاق رمز مميز (منتهي) بقائمة الانتظار للإشارة إلى اكتماله.

ملحوظة:إذا كان لديك العديد من سلاسل الإنتاج، فستحتاج إلى طريقة أكثر عمومية لاكتشاف وقت الانتهاء منها جميعًا.يمكنك تحقيق ذلك بنفس الإستراتيجية - يتم وضع علامة "منتهي" على كل مؤشر ترابط وينتهي المستهلك عندما يرى علامات num_threads.

نصائح أخرى

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

وأي. في العامل، لا شيء من هذا القبيل self.done = threading.Semaphore() في بداية العمل، وself.done.release() عند الانتهاء. في رمز سجلته أعلاه، بدلا من حلقة مشغول، فلا تفعل self.done.acquire(). عند الانتهاء من موضوع العامل، سوف تحكم العودة.

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

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

مثال:

time.clock()
while True:

    if len(self.output):
        yield self.output.pop(0)

    elif self.done or 15 < time.clock():
        if 15 < time.clock():
            yield "Maximum Execution Time Exceeded %s seconds" % time.clock()
            break

    time.sleep(0.01) # sleep for 10 milliseconds

وحدة استخدام مزامنة أو الحدث / إشارة

يجب عليك استخدام بدائية المزامنة هنا.انظر هنا: http://docs.python.org/library/threading.html.

تبدو كائنات الأحداث بسيطة جدًا ويجب أن تحل مشكلتك.يمكنك أيضًا استخدام كائن شرط أو إشارة.

لا أنشر مثالاً لأنني لم أستخدم كائنات الأحداث مطلقًا، وربما تكون البدائل أقل بساطة.


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

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