} } }

    《转》python线程池

    添加时间:2013-7-25 点击量:

    线程池的概念是什么?

    在IBM文档库中如许的一段描述:“在面向对象编程中,创建和烧毁对象是很费时候的,因为创建一个对象要获取内存资料或者其它更多资料。在Java中更是
    如此,虚拟机将试图跟踪每一个对象,以便可以或许在对象烧毁掉队行垃圾收受接管。所以进步办事法度效力的一个手段就是尽可能削减创建和烧毁对象的次数,希罕是一些
    很耗资料的对象创建和烧毁。如何哄骗已有对象来办事就是一个须要解决的关键题目,其实这就是一些池化资料技巧产生的原因。”--IBM文档库。



    按照IBM文档中的描述,我懂得为线程池是一个存放很多线程的单位,同时还有一个对应的任务队列。全部履行过程其实就是应用线程池中已有有限的线程把任务
    队列中的任务做完。如许做的益处就是你不须要为每个任务都创建一个线程,因为当你创建第100个线程来履行第100个任务的时辰,可能前面已经有50个线
    程停止工作了。是以反复哄骗线程来履行任务,削减体系资料的开销。

    一个不怎么恰当的比方就是,有100台电脑主机箱须要从1楼搬到2楼,你不须要喊来100人辅佐搬,你只须要叫十个或者二十小我就足以,每小我分派十个或者五个甚至是谁搬的快谁就多搬知道完成未知。(这个比方如同。。。。。)

    不管如何吧,大体上懂得了线程池的概念。那么怎么用python实现呢?我在网上找了一段代码,感觉不错,就收藏下来吧。贴上来大师瞧瞧。



    # !/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)



    斗劲网上其他的代码,我感觉这个代码还挺清楚易懂。

    全部代码只有两个类:WorkManager和Work,前者确切如定名所示,是一个经管者,经管线程池和任务队列,而后者就是具体的一个线程。

    它的全部运行逻辑就是,给WorkManager分派制订的任务量和线程数,然后每个线程都从任务队列中获取任务来履行,直到队列中没有任务。这里面也用到了Queue内部的同步机制(至于是啥同步机制今朝还没去研究)。

    总结一下如许一个线程池的感化,对于我底本的目标其实这个器材是永不上的,因为我须要在web页面来把握线程的启动和停止,而这个线程池看起来只是用来并发完任务的。不过我想固然在把握线程方面没有感化,然则它的并发履行任务的感化还是蛮不错,或容许以用在爬网页的项目组。

    在进一步思虑,或许我可以把WorkManager作为一个线程来运行,不过要怎么按需停止WorkManager内部线程池中线程的运行和停止呢。

    彼此相爱,却不要让爱成了束缚:不如让它成为涌动的大海,两岸乃是你们的灵魂。互斟满杯,却不要同饮一杯。相赠面包,却不要共食一个。一起歌舞欢喜,却依然各自独立,相互交心,却不是让对方收藏。因为唯有生命之手,方能收容你们的心。站在一起却不要过于靠近。—— 纪伯伦《先知》
    分享到: