pool线程池的使用

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功能下断点,充分领会代码的运行机制

------*** end*** ------