1. 程式人生 > >python concurrent.futures

python concurrent.futures

轉載自:

Python3.2帶來了 concurrent.futures 模組,這個模組具有執行緒池和程序池、管理並行程式設計任務、處理非確定性的執行流程、程序/執行緒同步等功能。

此模組由以下部分組成:

  • concurrent.futures.Executor: 這是一個虛擬基類,提供了非同步執行的方法。
  • submit(function, argument): 排程函式(可呼叫的物件)的執行,將 argument 作為引數傳入。
  • map(function, argument): 將 argument 作為引數執行函式,以 非同步 的方式。
  • shutdown(Wait=True): 發出讓執行者釋放所有資源的訊號。
  • concurrent.futures.Future: 其中包括函式的非同步執行。Future物件是submit任務(即帶有引數的functions)到executor的例項。

Executor是抽象類,可以通過子類訪問,即執行緒或程序的 ExecutorPools 。因為,執行緒或程序的例項是依賴於資源的任務,所以最好以“池”的形式將他們組織在一起,作為可以重用的launcher或executor。

2.1. 使用執行緒池和程序池

執行緒池或程序池是用於在程式中優化和簡化執行緒/程序的使用。通過池,你可以提交任務給executor。池由兩部分組成,一部分是內部的佇列,存放著待執行的任務;另一部分是一系列的程序或執行緒,用於執行這些任務。池的概念主要目的是為了重用:讓執行緒或程序在生命週期內可以多次使用。它減少了建立建立執行緒和程序的開銷,提高了程式效能。重用不是必須的規則,但它是程式設計師在應用中使用池的主要原因。

../_images/pooling-management.png

2.2. 準備工作

current.Futures 模組提供了兩種 Executor 的子類,各自獨立操作一個執行緒池和一個程序池。這兩個子類分別是:

  • concurrent.futures.ThreadPoolExecutor(max_workers)
  • concurrent.futures.ProcessPoolExecutor(max_workers)

max_workers 引數表示最多有多少個worker並行執行任務。

2.3. 如何做…

下面的示例程式碼展示了執行緒池和程序池的功能。這裡的任務是,給一個list number_list ,包含1到10。對list中的每一個數字,乘以1+2+3…+10000000的和(這個任務只是為了消耗時間)。

下面的程式碼分別測試了:

  • 順序執行
  • 通過有5個worker的執行緒池執行
  • 通過有5個worker的程序池執行

(譯者注:原文的程式碼是錯誤的,這裡貼出的程式碼以及執行結果是修改後的,詳見: 關於第四章第2節書中程式的疑問 #16 ,感謝 @Microndgt 提出) 程式碼如下::

import concurrent.futures
import time
number_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

def evaluate_item(x):
        # 計算總和,這裡只是為了消耗時間
        result_item = count(x)
        # 列印輸入和輸出結果
        return result_item

def  count(number) :
        for i in range(0, 10000000):
                i=i+1
        return i * number

if __name__ == "__main__":
        # 順序執行
        start_time = time.time()
        for item in number_list:
                print(evaluate_item(item))
        print("Sequential execution in " + str(time.time() - start_time), "seconds")
        # 執行緒池執行
        start_time_1 = time.time()
        with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
                futures = [executor.submit(evaluate_item, item) for item in number_list]
                for future in concurrent.futures.as_completed(futures):
                        print(future.result())
        print ("Thread pool execution in " + str(time.time() - start_time_1), "seconds")
        # 程序池
        start_time_2 = time.time()
        with concurrent.futures.ProcessPoolExecutor(max_workers=5) as executor:
                futures = [executor.submit(evaluate_item, item) for item in number_list]
                for future in concurrent.futures.as_completed(futures):
                        print(future.result())
        print ("Process pool execution in " + str(time.time() - start_time_2), "seconds")

執行這個程式碼,我們可以看到執行時間的輸出::

$ python3 pool.py
10000000
20000000
30000000
40000000
50000000
60000000
70000000
80000000
90000000
100000000
Sequential execution in 7.936585903167725 seconds
10000000
30000000
40000000
20000000
50000000
70000000
90000000
100000000
80000000
60000000
Thread pool execution in 7.633088827133179 seconds
40000000
50000000
10000000
30000000
20000000
70000000
90000000
60000000
80000000
100000000
Process pool execution in 4.787093639373779 seconds

2.4. 討論

我們建立了一個list存放10個數字,然後使用一個迴圈計算從1加到10000000,打印出和與 number_list 的乘積。:

def evaluate_item(x):
    # 計算總和,這裡只是為了消耗時間
    result_item = count(x)
    # 列印輸入和輸出結果
    print ("item " + str(x) + " result " + str(result_item))

def  count(number) :
    for i in range(0, 10000000):
        i=i+1
    return i * number

在主要程式中,我們先使用順序執行跑了一次程式::

if __name__ == "__main__":
    # 順序執行
    start_time = time.clock()
    for item in number_list:
        evaluate_item(item)
    print("Sequential execution in " + str(time.clock() - start_time), "seconds")

然後,我們使用了 futures.ThreadPoolExecutor 模組的執行緒池跑了一次::

with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
    for item in number_list:
        executor.submit(evaluate_item,  item)
print ("Thread pool execution in " + str(time.clock() - start_time_1), "seconds")

ThreadPoolExecutor 使用執行緒池中的一個執行緒執行給定的任務。池中一共有5個執行緒,每一個執行緒從池中取得一個任務然後執行它。當任務執行完成,再從池中拿到另一個任務。

當所有的任務執行完成後,打印出執行用的時間::

print ("Thread pool execution in " + str(time.clock() - start_time_1), "seconds")

最後,我們又用 ProcessPoolExecutor 跑了一次程式::

with concurrent.futures.ProcessPoolExecutor(max_workers=5) as executor:
    for item in number_list:
        executor.submit(evaluate_item,  item)

如同 ThreadPoolExecutor 一樣, ProcessPoolExecutor 是一個executor,使用一個執行緒池來並行執行任務。然而,和 ThreadPoolExecutor 不同的是, ProcessPoolExecutor 使用了多核處理的模組,讓我們可以不受GIL的限制,大大縮短執行時間。

相關推薦

python | concurrent.futures模塊提升數據處理速度

希望 數據預處理 exec resize 參考 margin 情況 neu folder p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px ".PingFang SC"; color: #454545 } p.p2 {

談談python concurrent.futures

Future 有幾個重要的方法: .done() 返回布林值,表示Future 是否已經執行 .add_done_callback() 這個方法只有一個引數,型別是可呼叫物件,Future執行結束後會回撥這個物件。 .result() 如果 Future 執行

python concurrent.futures

轉載自: Python3.2帶來了 concurrent.futures 模組,這個模組具有執行緒池和程序池、管理並行程式設計任務、處理非確定性的執行流程、程序/執行緒同步等功能。 此模組由以下部分組成: concurrent.futures.Executor: 這

Python並發編程之線程池/進程池--concurrent.futures模塊

when nod 模式 進程 d參數 executor 其他 done 對比 h2 { color: #fff; background-color: #f7af0d; padding: 3px; margin: 10px 0px } 一、關於concurrent.futur

python並發性能concurrent.futures

-1 兩個 size logs ssp int ces 底層 套接字 concurrent.futures模塊,可以利用multiprocessing實現真正的平行計算。核心原理是:concurrent.futures會以子進程的形式,平行的運行多個python解釋器,從而

Python Day37 python多線程標準模塊concurrent.futures

ont imp syn multi true 提交 使用 bmi define 1 介紹 concurrent.futures模塊提供了高度封裝的異步調用接口 ThreadPoolExecutor:線程池,提供異步調用 ProcessPoolExecutor: 進程池,提供

python全棧開發基礎【第二十六篇】(concurrent.futures模塊、協程、Greenlet、Gevent)

會有 什麽 www 上一個 join 開發 tps 初始化 brush 註意 1.不能無限的開進程,不能無限的開線程最常用的就是開進程池,開線程池。其中回調函數非常重要回調函數其實可以作為一種編程思想,誰好了誰就去掉2.只要你用並發,就會有鎖的問題,但是你不能一直去自己加鎖

python--線程池(concurrent.futures)

time pass ever 表示 iterator may 檢測 列表 多參數 1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 # author:love_cat 4 5 # 為什麽需要線程池 6 #

Python標準模組--concurrent.futures模組(ThreadPoolExecutor:執行緒池,提供非同步呼叫、ProcessPoolExecutor: 程序池,提供非同步呼叫)

目錄 ProcessPoolExecutor: 程序池 ThreadPoolExecutor:執行緒池  map的用法  回撥函式 https://docs.python.org/dev/library/concurrent.futures.html

網路爬蟲必備知識之concurrent.futurespython究竟要不要使用多執行緒

就庫的範圍,個人認為網路爬蟲必備庫知識包括urllib、requests、re、BeautifulSoup、concurrent.futures,接下來將結對concurrent.futures庫的使用方法進行總結 建議閱讀本博的博友先閱讀下上篇部落格: python究竟要不要使用多執行緒,將會對co

python 3 執行緒/程序池concurrent.futures模組使用

一、Executor和Future       concurrent.futures模組的基礎是Exectuor,Executor是一個抽象類,ThreadPoolExecutor和ProcessPoolExecutor是其非常有用的兩個子類。Future可以把它理

python併發之concurrent.futures

concurrent:併發   Python標準庫為我們提供了threading和multiprocessing模組編寫相應的多執行緒/多程序程式碼。從Python3.2開始,標準庫為我們提供了concurrent.futures模組,它提供了ThreadPoolExecutor和ProcessPoolEx

python非同步併發模組concurrent.futures簡析

本文主要介紹python非同步併發模組.。它非常簡單易用,主要用來實現多執行緒和多程序的非同步併發。 1. 模組安裝 2) python 2.7需要安裝模組,使用命令pip install futures安裝即可 2. Executor物件 class .f

python--利用concurrent.futures 來實現真正的平行計算

    由於python的全域性解釋鎖(GIL)使得我們無法使用執行緒進行真正的平行計算,因此,我們把總計算量分配到多個獨立的任務中,並在多個CPU和欣賞同時執行任務是很難實現的。    為解決該類問題,提高程式碼執行速率,我們嘗試可以引入concurrent.futures

python 併發之concurrent.futures----用於支援執行緒池和程序池

轉載自: https://blog.csdn.net/dutsoft/article/details/54728706一: 使用模組from concurrent.futures import ThreadPoolExecutor from concurrent.future

35、concurrent.futures模塊與協程

否則 ssp org 之間 內存 pat sta page hide concurrent.futures —Launching parallel tasks concurrent.futures模塊同時提供了進程池和線程池,它是將來的使用趨勢,同樣我們之前學習的進

Python3【模塊】concurrent.futures模塊,線程池進程池

tro containe them executor 進程池 自己的 from port clas   Python標準庫為我們提供了threading和multiprocessing模塊編寫相應的多線程/多進程代碼,但是當項目達到一定的規模,頻繁創建/銷毀進程或者線程是非

多進程 multiprocessing 多線程Threading 線程池和進程池concurrent.futures

不用 文件 進程池 lba ren 行操作 接收參數 出現 ali multiprocessing.procsess 定義一個函數 def func():pass 在if __name__=="__main__":中實例化 p = process(target=子進程要執

concurrent.futures模塊

繼續 循環 方法 nbsp call col 並不會 clas adp 1.concurrent.futures模塊介紹 2.ThreadPoolExecutor線程池使用 3.ProcessPoolExecutor進程池使用 1.concurrent.future