首页 > 代码库 > python里多线程的写法

python里多线程的写法

python里多线程的写法

 

今天用到python多线程的时候, 发现不知道如何正确的等待所有线程结束后再结束主线程.

其实到最后我才知道这都是杞人忧天, Thread()出来的实例本来就是等到主进程结束后才结束.

官方解释:

daemon A boolean value indicating whether this thread is a daemon thread (True) or not (False). This must be set before start() is called, otherwise RuntimeError is raised. Its initial value is inherited from the creating thread; the main thread is not a daemon thread and therefore all threads created in the main thread default to daemon = False.

The entire Python program exits when no alive non-daemon threads are left.

默认daemon是false, start之后也不会阻塞在那里(废话, 否则要多线程干嘛, 不过总会想到join会阻塞这点). 对于我的需要来说简直完美,其实什么都不用做嘛.

可以用setDaemon(True)改变daemon值. 这样的话, 就需要调用join等待子线程结束了. (好多此一举..)

for t in threads: t.join()

可以把所有要起的线程放到一个队列里面, 然后对每一个线程join. 这样的确是可以实现, 但看起来太丑, 用着实在别扭.

像如下这样, 其实for循环里面, 进程等待在第一个join那里:

#!/usr/bin/env python# -*- coding: utf-8 -*-from threading import Threadimport timedef target(i):    time.sleep(10-i)def main():    threads = []    for i in range(10):        t = Thread(target=target,args=(i,))        threads.append(t)    for t in threads:        t.start()    for idx,t in enumerate(threads):        print idx        t.join()if __name__ == ‘__main__‘:    main()

multiprocessing.Pool

又用Queue实现了一下, 但还是太丑陋, 封装不好. 然后才搜索到Python其实有个multiprocessing.Pool, 可以很好看的实现这个功能:

#!/usr/bin/env python# -*- coding: utf-8 -*-from multiprocessing import Poolimport timedef work():    print time.time()    time.sleep(4)def main():    pool = Pool(processes=4)    for i in range(4):        pool.apply_async(work)    pool.close()    pool.join()if __name__ == ‘__main__‘:    main()

借鉴官方的Pool, 尝试自己实现一下最简单的Multiprocessing Pool

#!/usr/bin/env python# -*- coding: utf-8 -*-from threading import Threadfrom Queue import Queueimport timedef hello(msg=None):    print time.time(),msg    time.sleep(5)class MPool(object):    def posttask(self,func):        def inner(*args, **kwargs):            q = args[0]            real_args = args[1:]            func(*real_args, **kwargs)            q.task_done()        return inner    def __init__(self):        self._queue = Queue() #简单起见没有设置队列上限    def run_task(self, target, *args, **kwargs):        task = Thread(target=self.posttask(target), args=(self._queue,)+args, kwargs=kwargs)        self._queue.put(task)        task.setDaemon(True)        task.start()    def join(self):        self._queue.join()def main():    p = MPool()    for i in range(10):        p.run_task(hello,i)    p.join()if __name__ == ‘__main__‘:    main()

最后再提一下, 我的初衷只是想等所有线程结束后再退出. 默认就是这样的, join什么的都不用.

python里多线程的写法