天天看点

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>