进程池与线程池
线程池与进程池
线程池的创建需要导入模块
1
from concurrent.futures import ThreadPoolExecutor
创建一个线程池,并且指定最大的线程数
1
executor = ThreadPoolExecutor(max_workers=3)
返回任务句柄task1,可对task查看任务状态
1
task = executor.submit(get_html, 1)
向线程池中提交函数,线程池会自动分配任务,第一位是函数名,后面全是参数
submit函数立即执行,不会阻塞主线程
检查任务是否完成
1
task.done()
取消任务的执行,该任务没有放入线程池才能成功取消
1
task.cancel()
拿到任务执行结果,是个阻塞方法,可通过timeout设置超时时间
1
task.result()
as_comoleted是一个生成器,会阻塞,知道所有任务执行完成,也就是说每个任务执行完成就会迭代,然后阻塞
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15from concurrent.futures import ThreadPoolExecutor, as_completed, wait, ALL_COMPLETED, FIRST_COMPLETED
executor = ThreadPoolExecutor(max_workers=3)
def get_html(times):
time.sleep(times)
print('获取网页完毕,执行{}s'.format(times))
urls = [4, 2, 3]
all_task = [executor.submit(get_html, url) for url in urls]
for item in as_completed(all_task):
data = item.result()
print("主线程中获取任务的返回值是{}".format(data))
for data in executor.map(get_html, urls):
print("主线程中获取任务的返回值是{}".format(data))
#map会把任务和参数映射
wait(all_task, return_when=ALL_COMPLETED) #主线程等待,知道满足什么条件时继续执行as_completed和map的区别,它们都能拿到任务的完成结果,但是as_completed会根据任务的快慢返回结果,map不管任务快慢,严格按照传参顺序返回结果
进程池
进程有两种实现方式,一种与线程用法完全相同,也是从concurrent.futures ProcessExecutePool
另一种为multiprocessing
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21import multiprocessing
import time
def get_html(n):
time.sleep(n)
print("{}子进程获取内容成功".format(n))
return n
if __name__ == '__main__':
#通过cpu_count获取当前主机的核心数
pool = multiprocessing.Pool(multiprocessing.cpu_count())
#异步方法
result = pool.apply_async(get_html, args=(3,))
pool.close()
#必须在join前调用此方法
pool.join()
result.get()
#子进程执行的结果
#imap_unordered 无序先完成的先输出
for result in pool.imap(get_html, [1, 2, 3]):
print("{}休眠执行成功".format(result))
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 JHMARK!