因为python有GIL(Global Interpreter Lock(全局解释器锁)),无论cpu是不是多核cpu,其同一时刻只能有一个线程使用cpu,所以多线程适用于I/O密集型任务,多进程适用于cpu密集型任务。
线程池
concurrent.futures 模块提供异步执行回调高层接口。
异步执行可以由 ThreadPoolExecutor 使用线程来实现。
使用多线程并得到线程返回的结果示例:
from concurrent.futures import ThreadPoolExecutor
def max_1(a):
if a == 5:
time.sleep(5)
print("sleep 5s",a)
if a == 6:
time.sleep(3)
print("sleep 3s", a)
return a
def test_pool():
list1 = []
seed = [1, 2, 3, 4, 5, 3]
with ThreadPoolExecutor(6) as executor:
for each in seed:
if each > 1:
each += 2
res = executor.submit(max_1, each)
#print(res.result()) # 注:不可在此获取线程返回的结果,否则线程会被阻塞,顺序执行
list1.append(res)
return list1
if __name__ == '__main__':
# main()
start = time.time()
res_list = test_pool()
for res in res_list:
print(res.result()) # 得到线程返回的结果
end = time.time()
print('总耗时:%.2f s' % (end - start))
注:res.result()不可在分配线程执行任务后使用,可以使用列表或队列将保存其返回的对象,执行完毕后,利用result()方法得到返回的结果。
进程池
multiprocessing 包同时提供了本地和远程并发操作,通过使用子进程而非线程有效地绕过了 全局解释器锁。 因此,multiprocessing 模块允许程序员充分利用给定机器上的多个处理器。 它在 Unix 和 Windows 上均可运行。但是在windows中使用,只能将多进程写在if name == ‘main’:后。
使用多进程并得到进程返回结果示例:
import multiprocessing
def max_1(a):
if a == 5:
time.sleep(5)
print("sleep 5s",a)
if a == 6:
time.sleep(3)
print("sleep 3s", a)
return a
if __name__ == '__main__':
start = time.time()
pool = multiprocessing.Pool(5)
seed = [1, 2, 3, 4, 5, 3]
result = []
for each in seed:
res = pool.apply_async(max_1, args=(each, ))
#print(res.get()) # 注:不可在此获取进程返回的结果,否则进程会被阻塞,顺序执行
result.append(res)
pool.close()
pool.join()
for res in result:
print(res.get()) # 得到进程返回的结果
end = time.time()
print('总耗时:%.2f s' % (end - start))
注:res.get()不可在分配线程执行任务后使用,可以使用列表或队列将保存其返回的对象,执行完毕后,利用get()方法得到返回的结果。