zoukankan      html  css  js  c++  java
  • 进程池线程池

    模块:ThreadPoolExecutor,ProcessPoolExecutor
    导入方法:
        from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
    原理:
        concurrent.futures是异步调用的机制
    模块区分:
        from multiprocessing import Pool.apply/apply_async   既可同步也可异步
    区分:
        进程池中进程的数量为计算机核数+1
        线程池中线程的数量为计算机核数*5
        进程池中的回调函数是父进程调用的,和子进程没有关系
        线程池中的回调函数是子线程调用的,和父进程没有关系
    模块方法:
        shutdown()  等效于进程池Pool中的close和join的组合
    使用方法:
        提交任务用submit
    再强调:
        如果程序的IO操作比较多,则采用多线程的方式,因为多线程的切换速度比多进程快
        如果程序的计算比较多,则采用多进程的方式
    
        
    小结:针对计算密集的程序来说,Pool或者ProcessPoolExecutor执行效率相当,而ThreadPoolExecutor相对于前两者效率更差
          所以当计算密集时使用多进程
    
    #######线程池(进程池)(多任务提交)
    from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
    import time
    
    def func(num):
        sum = 0
        #求参数范围内的平方和
        for i in range(num):
            sum += i**2
        print(sum)
    
    if __name__ == '__main__':
        #实例化线程池对象
        #tp=ProcessPoolExecutor(5)    #进程池只需改成ProcessPoolExecutor并且参数为操作系统核数+1即可
        tp=ThreadPoolExecutor(20)     #线程池中线程的数量为操作系统核数*5
        #计算程序执行到这里的时间,目的是为了能比较效率
        start = time.time()
        #准备开启1000个线程
        for i in range(1000):
            #提交给线程池开始执行线程的任务
            tp.submit(func,i)
        #以上的for循环可以用下列map函数代替
        #t.map(func,range(1000))    #map返回的结果是一个生成器对象
        tp.shutdown()   #主线程等待所有子线程执行完毕,相当于进程池中的close和join的组合
        #计算程序执行到这里的时间,并减去start,获得线程池中所有线程执行的时间效率
        print("线程池的消耗时间为{}".format(time.time() - start))
        
        
    ##########线程池的返回值
    from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
    import time
    
    
    def func(num):
        sum = 0
        for i in range(num):
            sum += i**2
        return sum
    
    
    if __name__ == '__main__':
        t=ThreadPoolExecutor()
        res_l = []  #用于存放线程池中线程返回的结果
        for i in range(1000):
            re = t.submit(func,i)
            res_l.append(re)
        #t.shutdown() #此时不用到shutdown()原因是每个线程执行完都需要返回结果给re,所以每个线程在此约束条件下会完整的执行,而不会中途丢掉结果而去执行下一个任务
        #此时的程序依然是采用异步的机制,只不过因为需要获得返回每个线程的返回值所以才会出现类似同步的现象
        [print(i.result()) for i in res_l]
        #在Pool中获得结果是用get方法,而在ThreadPoolExecutor获得结果是用result方法
        #如果提交任务的方式采用的是map方法,则在获得结果时需要做一定的修改
        #res = t.map(func,range(1000))  返回的是一个生成器对象
        #t.shutdown()
        #res.__next__()  是获取单个结果,若需要获取多个结果采用for循环即可
        
    
    
        
        
    ########进程池中的回调函数(Pool也有回调函数)
    from concurrent.futures import ProcessPoolExecutor
    # 不管是ProcessPoolExecutor的进程池  还是Pool的进程池,回调函数都是父进程调用的。
    import os
    import requests
    
    def func(num):
        sum = 0
        for i in range(num):
            sum += i ** 2
        return sum
    
    def call_back_fun(res):
        # print(res.result(),os.getpid())
        print(os.getpid())
    
    if __name__ == '__main__':
        print(os.getpid())
        t = ProcessPoolExecutor(20)
        for i in range(1000):
            t.submit(func,i).add_done_callback(call_back_fun)
        t.shutdown()
  • 相关阅读:
    轻重搭配
    EF的优缺点
    使用bootstrap-select有时显示“Nothing selected”
    IIS发布 HTTP 错误 500.21
    js添加的元素无法触发click事件
    sql server查看表是否死锁
    sql server把一个库表的某个字段更新到另一张表的相同字段
    SQLSERVER排查CPU占用高的情况
    SQL server中如何按照某一字段中的分割符将记录拆成多条
    LINQ to Entities does not recognize the method 'System.DateTime AddDays(Double)' method, and this method cannot be translated into a store expression.
  • 原文地址:https://www.cnblogs.com/god-for-speed/p/11719106.html
Copyright © 2011-2022 走看看