進程池線程池

模塊: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()
相關文章
相關標籤/搜索