python线程池(concurrent.futuresl)模块

转自:https://www.jianshu.com/p/b9b3d66aa0be

Python中已经有了threading模块,为什么还需要线程池呢,线程池又是什么东西呢?在介绍线程同步的信号量机制的时候,举得例子是爬虫的例子,需要控制同时爬取的线程数,例子中创建了20个线程,而同时只允许3个线程在运行,但是20个线程都需要创建和销毁,线程的创建是需要消耗系统资源的,有没有更好的方案呢?其实只需要三个线程就行了,每个线程各分配一个任务,剩下的任务排队等待,当某个线程完成了任务的时候,排队任务就可以安排给这个线程继续执行。

这就是线程池的思想(当然没这么简单),但是自己编写线程池很难写的比较完美,还需要考虑复杂情况下的线程同步,很容易发生死锁。从Python3.2开始,标准库为我们提供了concurrent.futures模块,它提供了ThreadPoolExecutorProcessPoolExecutor两个类,实现了对threadingmultiprocessing的进一步抽象(这里主要关注线程池),不仅可以帮我们自动调度线程,还可以做到:

  1. 主线程可以获取某一个线程(或者任务的)的状态,以及返回值。
  2. 当一个线程完成的时候,主线程能够立即知道。
  3. 让多线程和多进程的编码接口一致。

实例

简单使用

 1 from concurrent.futures import ThreadPoolExecutor
 2 import time
 3 import os
 4 
 5 def copy_file(old_folder_name, new_folder_name):
 6     file_names = os.listdir(old_folder_name)
 7     for file_name in file_names:
 8         print("已拷贝文件:%s" % (new_folder_name+'/'+file_name))
 9     return 3
10 
11 
12 executor = ThreadPoolExecutor(max_workers=3)
13 # 通过submit函数提交执行的函数到线程中,submit函数立即返回,不堵塞
14 old_folder_name = 'test1'
15 new_folder_name = 'test1[复件]'
16 task = executor.submit(copy_file, old_folder_name, new_folder_name)
17 # done方法用于判断某个人物是否完成
18 print(task.done())
19 # cancel方法用于取消某个任务,该任务没有放入线程池中才能取消成功
20 print(task.cancel())
21 time.sleep(4)
22 print(task.done())
23 # result方法可以获取task的执行结果
24 print(task.result())

  运行结果:

False
False
已拷贝文件:test1[复件]/_compat_pickle.py
已拷贝文件:test1[复件]/_compression.py
已拷贝文件:test1[复件]/_dummy_thread.py
已拷贝文件:test1[复件]/_markupbase.py
已拷贝文件:test1[复件]/_osx_support.py
已拷贝文件:test1[复件]/_pydecimal.py
已拷贝文件:test1[复件]/_pyio.py
已拷贝文件:test1[复件]/_py_abc.py
True
3
原文地址:https://www.cnblogs.com/zzmx0/p/12770571.html