天天看點

python異步并發子產品concurrent.futures簡析

1. 子產品安裝

2. executor對象

executor是一個抽象類,它提供了異步執行調用的方法。它不能直接使用,但可以通過它的兩個子類threadpoolexecutor或者processpoolexecutor進行調用。

fn:需要異步執行的函數

*args, **kwargs:fn參數

示例:

1

2

3

4

5

6

7

8

9

10

11

12

13

<code>#-*- coding:utf-8 -*-</code>

<code>from concurrent import futures</code>

<code>def test(num):</code>

<code>    </code><code>import time</code>

<code>    </code><code>return time.ctime(),num</code>

<code>with futures.threadpoolexecutor(max_workers=1) as executor:</code>

<code>    </code><code>future = executor.submit(test,1)</code>

<code>    </code><code>print future.result()</code>

<code>&gt;&gt;&gt;</code>

<code>('tue jan 17 15:23:10 2017', 1)</code>

func:需要異步執行的函數

*iterables:可疊代對象,如清單等。每一次func執行,都會從iterables中取參數。

timeout:設定每次異步操作的逾時時間

14

15

16

<code>data=[1,2,3]</code>

<code>    </code><code>for future in executor.map(test,data):</code>

<code>        </code><code>print future</code>

<code>('tue jan 17 15:23:47 2017', 1)</code>

<code>('tue jan 17 15:23:47 2017', 2)</code>

<code>('tue jan 17 15:23:47 2017', 3)</code>

2.3 executor.shutdown(wait=true)

3. threadpoolexecutor對象

threadpoolexecutor類是executor子類,使用線程池執行異步調用.

class concurrent.futures.threadpoolexecutor(max_workers)

使用max_workers數目的線程池執行異步調用

4. processpoolexecutor對象

threadpoolexecutor類是executor子類,使用程序池執行異步調用.

class concurrent.futures.processpoolexecutor(max_workers=none)

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

<code>def muti_exec(m,n):</code>

<code>    </code><code>#m 并發次數</code>

<code>    </code><code>#n 運作次數</code>

<code>    </code><code>with futures.processpoolexecutor(max_workers=m) as executor: #多程序</code>

<code>    </code><code>#with futures.threadpoolexecutor(max_workers=m) as executor: #多線程</code>

<code>        </code><code>executor_dict=dict((executor.submit(test,times), times) for times in range(m*n))</code>

<code>    </code><code>for future in futures.as_completed(executor_dict):</code>

<code>        </code><code>times = executor_dict[future]</code>

<code>        </code><code>if future.exception() is not none:</code>

<code>            </code><code>print('%r generated an exception: %s' % (times,future.exception()))</code>

<code>        </code><code>else:</code>

<code>            </code><code>print('runtimes:%d,res:%s'% (times, future.result()))</code>

<code>if __name__ == '__main__':</code>

<code>    </code><code>muti_exec(5,1)</code>

<code>runtimes:0,res:('tue jan 17 15:56:53 2017', 0)</code>

<code>runtimes:4,res:('tue jan 17 15:56:53 2017', 4)</code>

<code>runtimes:3,res:('tue jan 17 15:56:53 2017', 3)</code>

<code>runtimes:1,res:('tue jan 17 15:56:53 2017', 1)</code>

<code>runtimes:2,res:('tue jan 17 15:56:53 2017', 2)</code>

那麼,不同線程同時通路時,資料的保護機制是怎樣的呢?答案是解釋器全局鎖。從名字上看能告訴我們很多東西,很顯然,這是一個加在解釋器上的全局(從解釋器的角度看)鎖(從互斥或者類似角度看)。這種方式當然很安全,但是它有一層隐含的意思(python初學者需要了解這個):對于任何python程式,不管有多少的處理器,任何時候都總是隻有一個線程在執行。

是以,對于計算密集型的,我還是建議不要使用python的多線程而是使用多程序方式,而對于io密集型的,還是勸你使用多程序方式,因為使用多線程方式出了問題,最後都不知道問題出在了哪裡,這是多麼讓人沮喪的一件事情!

6. 參考文檔

<a href="http://pythonhosted.org/futures/">http://pythonhosted.org/futures/</a>