• 进程池 & 线程池


     

    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)
    复制代码

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

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

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

  • 相关阅读:
    IDEA中Spring Boot项目MyBaits提示Invalid bound statement (not found)错误
    js 算法 两个数组比较去重,性能优化
    window.open() 打开新标签,之前的sessionStorage还在
    自定义<el-table-column> 数据格式:数组对象,且每条对象中有一个数组对象
    VSCode 代码格式化 快捷键
    echarts的饼图label标签重叠解决办法
    vue打包 element-icons.woff 和element-icons.ttf 字体文件路径错误,导致icon图标显示成小方块的问题。
    vue中的$refs属性几个注意点
    js中的 || 与 && 运算符详解
    package.json与package-lock.json文件是干什么用的?
  • 原文地址:https://www.cnblogs.com/pupy/p/11377309.html
Copyright © 2020-2023  润新知