进程池 & 线程池

 

https://www.cnblogs.com/lddragon/p/11358948.html       # 抄的

进程池与线程池

什么是池?


  在保证计算机硬件安全的情况下最大限度的利用计算机  
     池其实是降低了程序的运行效率,但是保证了计算机硬件的安全  
     (硬件的发展跟不上软件的速度)

进程池与线程池


  开进程开线程都需要消耗资源,只不过两者比较的情况 线程消耗的资源比较少
  在计算机能够承受范围之内最大限度的利用计算机

 

如何创建线程池 / 进程池?

  模块导入 from concurrent.futures import ThreadPoolExecutor / ProcessPoolExecutor

  生成一个线程池 / 进程池 对象

     T = ThreadPoolExecutor() 括号内可以传参数指定线程池内的线程个数也可以不传;

                   不传默认是当前所在计算机的cpu个数乘5

     P = ProcessPoolExecutor()  默认是当前计算机cpu的个数

  ps:池子中创建的进程 / 线程创建一次就不会再创建了,至始至终用的都是最初的那几个

      这样的话节省了反复开辟进程/线程的资源

  进程需要在 main 下提交任务,线程建议也这样

复制代码
from concurrent.futures import ProcessPoolExecutor

p = ProcessPoolExecutor(5)

def task(n):
    print(n)
    
if __name__ == '__main__':
    for i in range(10):
        p.submit(task, i)
复制代码

  创建的函数其实就是你的进程 / 线程执行的任务

   使用 submit() 方法来提交任务          *** submit 是异步提交  

        第一个参数 执行的任务(函数)

           第二个参数:任务(函数)的参数     

                 用逗号隔开

 

    同步: 提交任务之后 原地等待任务的返回结果 期间不做任何事

    异步: 提交任务之后 不原地等待返回结果 直接执行下一行代码 结果是要的 通过其他方式来拿

  submit 提交任务之后,任务完成会有一个返回值,是一个对象 

复制代码
from concurrent.futures import ProcessPoolExecutor

p = ProcessPoolExecutor(5)

def task(n):
    print(n)
    
if __name__ == '__main__':
    for i in range(10):
       res = p.submit(task, i)  我使用res来接收这个对象
       print(res.result())   其中有个方法可以查看结果 result
复制代码

  使用 result 可以查看对象的结果,但是不能直接在 submit 后直接使用 result;

  因为任务提交之后是不会直接有返回结果的,而 result 就相当于等待这个结果;此时异步就会变成串行了

复制代码
from concurrent.futures import ProcessPoolExecutor

p = ProcessPoolExecutor(5)

def task(n):
    print(n)
    return n**2
if __name__ == '__main__':
    a =[]
    for i in range(10):
        res = p.submit(task, i)
        a.append(res)
    p.shutdown()

    for i in a:
        print(i.result())
复制代码

  shutdown() 方法     关闭进程 / 线程池入口 :等待池子中所有的任务执行完毕之后才会往下运行代码;相当于 join

  异步回调机制:当异步提交的任务有返回结果之后,会 自动触发回调函数 的执行

  方法 .add_done_callback() 括号内填一个函数名 ,函数需要有一个参数,这个参数会自动传入 — submit 的返回对象

  提交任务的时候绑定一个回调函, 一旦该任务有结果,立刻执行对应的回调函数

复制代码
from concurrent.futures import ProcessPoolExecutor

p = ProcessPoolExecutor(5)

def task(n):
    print(n)
    return n**2

def callback(n):  # 这里面的n是任务task函数执行完毕后的返回结果
    print('>>>>', n.result())

if __name__ == '__main__':
    a =[]
    for i in range(10):
        p.submit(task, i).add_done_callback(callback)
复制代码

线程池和进程池的操作几乎一样,唯一一点区别:

  进程的回调函数是:主线程执行的   

  线程的回调函数是:谁腾出手来谁来干

原文地址:https://www.cnblogs.com/pupy/p/11377309.html