Heim  >  Artikel  >  Backend-Entwicklung  >  Weiteres Verständnis des Python-Thread-Pools

Weiteres Verständnis des Python-Thread-Pools

高洛峰
高洛峰Original
2016-10-19 15:13:131306Durchsuche

Was ist das Konzept des Thread-Pools?

Bei der objektorientierten Programmierung ist das Erstellen und Zerstören von Objekten sehr zeitaufwändig, da zum Erstellen eines Objekts Speicherressourcen oder andere Ressourcen benötigt werden. Dies gilt insbesondere für Java, wo die virtuelle Maschine versucht, jedes Objekt zu verfolgen, damit es nach der Zerstörung des Objekts durch den Müll gesammelt werden kann. Daher besteht eine Möglichkeit zur Verbesserung der Effizienz von Serviceprogrammen darin, die Anzahl der erstellten und zerstörten Objekte so weit wie möglich zu reduzieren, insbesondere die Erstellung und Zerstörung einiger ressourcenintensiver Objekte. Die Verwendung vorhandener Objekte für die Bereitstellung ist ein zentrales Problem, das gelöst werden muss. Tatsächlich ist dies der Grund für die Entstehung einiger „Pooled Resource“-Technologien.

Ich verstehe, dass der Thread-Pool eine Einheit ist, die viele Threads speichert, und es gibt auch eine entsprechende Aufgabenwarteschlange. Der gesamte Ausführungsprozess besteht tatsächlich darin, die begrenzten Threads im Thread-Pool zu verwenden, um die Aufgaben in der Aufgabenwarteschlange abzuschließen. Dies hat den Vorteil, dass Sie nicht für jede Aufgabe einen Thread erstellen müssen, denn wenn Sie den 100. Thread erstellen, um die 100. Aufgabe auszuführen, haben möglicherweise die vorherigen 50 Threads ihre Arbeit abgeschlossen. Daher werden Threads wiederverwendet, um Aufgaben auszuführen und den Overhead der Systemressourcen zu reduzieren.

Eine unangemessene Metapher ist, dass 100 Computer-Großrechner vom ersten Stock in den zweiten Stock gebracht werden müssen. Sie müssen nicht 100 Leute anrufen, um beim Umzug zu helfen oder zwanzig Leute, jeder Person sind zehn oder fünf zugeteilt, und wer sich schneller bewegt, wird sich mehr bewegen, bis die Vollendung unbekannt ist. (Diese Metapher scheint...)

Jedenfalls verstehe ich im Allgemeinen das Konzept des Thread-Pools. Wie implementiert man es also in Python?

Der Code lautet wie folgt

# !/usr/bin/env python
# -*- coding:utf-8 -*-
# ref_blog:http://www.open-open.com/home/space-5679-do-blog-id-3247.html
import Queue
import threading
import time
class WorkManager(object):
    def __init__(self, work_num=1000,thread_num=2):
        self.work_queue = Queue.Queue()
        self.threads = []
        self.__init_work_queue(work_num)
        self.__init_thread_pool(thread_num)
    """
        初始化线程
    """
    def __init_thread_pool(self,thread_num):
        for i in range(thread_num):
            self.threads.append(Work(self.work_queue))
    """
        初始化工作队列
    """
    def __init_work_queue(self, jobs_num):
        for i in range(jobs_num):
            self.add_job(do_job, i)
    """
        添加一项工作入队
    """
    def add_job(self, func, *args):
        self.work_queue.put((func, list(args)))#任务入队,Queue内部实现了同步机制
    """
        检查剩余队列任务
    """
    def check_queue(self):
        return self.work_queue.qsize()
    """
        等待所有线程运行完毕
    """ 
    def wait_allcomplete(self):
        for item in self.threads:
            if item.isAlive():item.join()
class Work(threading.Thread):
    def __init__(self, work_queue):
        threading.Thread.__init__(self)
        self.work_queue = work_queue
        self.start()
    def run(self):
        #死循环,从而让创建的线程在一定条件下关闭退出
        while True:
            try:
                do, args = self.work_queue.get(block=False)#任务异步出队,Queue内部实现了同步机制
                do(args)
                self.work_queue.task_done()#通知系统任务完成
            except Exception,e:
                print str(e)
                break
#具体要做的任务
def do_job(args):
    print args
    time.sleep(0.1)#模拟处理时间
    print threading.current_thread(), list(args)
if __name__ == '__main__':
    start = time.time()
    work_manager =  WorkManager(10, 2)#或者work_manager =  WorkManager(10000, 20)
    work_manager.wait_allcomplete()
    end = time.time()
    print "cost all time: %s" % (end-start)

Dieser Code ist klar und leicht zu verstehen.

Im gesamten Code gibt es nur zwei Klassen: WorkManager und Work. Erstere ist tatsächlich ein Manager, der den Thread-Pool und die Aufgabenwarteschlange verwaltet, während letztere ein spezifischer Thread ist.

Seine gesamte Betriebslogik besteht darin, WorkManager die angegebene Anzahl von Aufgaben und Threads zuzuweisen. Anschließend erhält jeder Thread Aufgaben aus der Aufgabenwarteschlange und führt sie aus, bis keine Aufgaben mehr in der Warteschlange vorhanden sind. Hier wird auch der interne Synchronisationsmechanismus von Queue verwendet (der Synchronisationsmechanismus wurde noch nicht untersucht).

Um die Rolle eines solchen Thread-Pools zusammenzufassen: Für meinen ursprünglichen Zweck wird dieses Ding niemals verwendet, da ich das Starten und Stoppen von Threads auf der Webseite steuern muss, und dieser Thread-Pool scheint dies zu tun werden nur zum gleichzeitigen Erledigen von Aufgaben verwendet. Ich denke jedoch, dass es zwar keine Auswirkung auf die Steuerung von Threads hat, aber dennoch eine recht gute Rolle bei der gleichzeitigen Ausführung von Aufgaben spielt und beim Crawlen von Webseiten verwendet werden kann.


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn