1 线程池的原理和使用
问题的提出:
在使用多线程的时候面对着一个问题,如果使用断点下载,把每个range设置为指定值,文件大或者range小都会面对一个任务数爆炸的状态。使用一个线程来完成一个任务会造成线程数过多,线程数过多不仅影响效率,也会影响程序的健壮性
2 线程池的原理
1.线程池首先会维护一个任务队列 2.生成工作使用的线程(可以是自定义个数,也可以是系统默认) 3.线程分别从队列中取出任务,并执行,一个任务执行完成需要告诉主线程完成一个任务 4.再从任务队列中取出任务,直到所有任务为空,退出线程
3 具体使用
A 新建单一进程
import multiprocessing import time
def func(msg):
print(msg)
time.sleep(1)
if __name__ == "__main__":
#将函数作为第一个参数传入Process中,注意函数不能是类里面的函数,只能是独立定义的
#把args参数作为第二个参数传入Process中,注意下面例子中的args=("hello ", )是打包成了元组类型,可迭代,但是里面只有一个元素
#func("Josn")
p = multiprocessing.Process(target = func,args = ("hello ",))
p.start()
p.join()
print("Done!")
B 使用进程池
import multiprocessing
import time
def func(msg):
print(msg)
time.sleep(1)
if __name__ == "__main__":
pool = multiprocessing.Pool()
for item in range(3):
msg = "hello " + str(item)
pool.apply_async(func, (msg,))
pool.close()
pool.join()#用来等待进程池中的worker进程完毕,防止主进程在worker进程结束前结束,但pool.join()必须在pool.close()之后
print("Done!")
使用 pool.apply_async()的道理和pool.map()一样,注意的是第二个参数一定是可以迭代的,即函数一个个传进去对应着前面的函数,利用pool.map()创建工程如下
C 利用map函数修改
import multiprocessing
import time
def func(msg)
print(msg)
time.sleep(2)
if __name__ == "__main__":
pool = multiprocessing.Pool()
msg_list = []
for item in range(4):
msg_list.append("hello " + str(item))
pool.close()
pool.join()
print("Done!")
总结
学会利用pycharm的debug功能下断点,充分领会代码的运行机制