سؤال

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

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

أنا لا أعرف الكثير عن المواضيع، ولكن يبدو وكأنه خيوط قد تساعد الوحدة؟ أو ربما هناك بعض الطرق السهلة التي أغفلتها.

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

المحلول

ربما ستستفيد من threading أو multiprocessing وحدات. أنت لا تحتاج في الواقع لخلق كل تلك Threadالطبقات المعدية بنفسك، هناك طريقة أبسط باستخدام Pool.map:

from multiprocessing import Pool

def fetch_url(url):
    # Fetch the URL contents and save it anywhere you need and
    # return something meaningful (like filename or error code),
    # if you wish.
    ...

pool = Pool(processes=4)
result = pool.map(f, image_url_list)

نصائح أخرى

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

كما هو مبين بحق، يمكنك إنشاء عدد من الخيوط، كل منها مسؤول عن أداء عمليات URLRrererive. هذا يسمح للخيط الرئيسي للمتابعة دون انقطاع.

إليك برنامج تعليمي حول الخيوط في بيثون:http://heather.cs.ucdavis.edu/~matloff/python/pythread.pdf.

إليك مثال على كيفية استخدام Threading.Thread. ما عليك سوى استبدال اسم الفصل بنفسك ووظيفة التشغيل بنفسك. لاحظ أن الخيوط رائعة للتطبيقات المقيدة IO مثلك ويمكن أن تسرع فيه حقا. باستخدام خيوط Pythong بشكل صارم للحساب في Python القياسي لا يساعد لأن مؤشر ترابط واحد فقط يمكن أن يحسب في وقت واحد.

import threading, time
class Ping(threading.Thread):
    def __init__(self, multiple):
        threading.Thread.__init__(self)
        self.multiple = multiple
    def run(self):
        #sleeps 3 seconds then prints 'pong' x times
        time.sleep(3)
        printString = 'pong' * self.multiple

pingInstance = Ping(3)
pingInstance.start() #your run function will be called with the start function
print "pingInstance is alive? : %d" % pingInstance.isAlive() #will return True, or 1
print "Number of threads alive: %d" % threading.activeCount()
#main thread + class instance
time.sleep(3.5)
print "Number of threads alive: %d" % threading.activeCount()
print "pingInstance is alive?: %d" % pingInstance.isAlive()
#isAlive returns false when your thread reaches the end of it's run function.
#only main thread now

لديك هذه الخيارات:

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

أوصي فقط باستخدام الخيوط إلا إذا كنت بحاجة إلى جفاف على نطاق صناعي.

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

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