简单实现并发:python concurrent模块

简介:

可以使用python 3中的concurrent模块,如果python环境是2.7的话,需要下载https://pypi.python.org/packages/source/f/futures/futures-2.1.6.tar.gz#md5=cfab9ac3cd55d6c7ddd0546a9f22f453

此futures包即可食用concurrent模块。

官方文档:http://pythonhosted.org//futures/


对于python来说,作为解释型语言,Python的解释器必须做到既安全又高效。我们都知道多线程编程会遇到的问题,解释器要留意的是避免在不同的线程操作内部共享的数据,同时它还要保证在管理用户线程时保证总是有最大化的计算资源。而python是通过使用全局解释器锁来保护数据的安全性

python代码的执行由python虚拟机来控制,即Python先把代码(.py文件)编译成字节码(字节码在Python虚拟机程序里对应的是PyCodeObject对象,.pyc文件是字节码在磁盘上的表现形式),交给字节码虚拟机,然后虚拟机一条一条执行字节码指令,从而完成程序的执行。python在设计的时候在虚拟机中,同时只能有一个线程执行。同样地,虽然python解释器中可以运行多个线程,但在任意时刻,只有一个线程在解释器中运行。而对python虚拟机的访问由全局解释器锁来控制,正是这个锁能保证同一时刻只有一个线程在运行。在多线程的环境中,python虚拟机按一下方式执行:

1,设置GIL(global interpreter lock).

2,切换到一个线程执行。

3,运行:

    a,指定数量的字节码指令。

    b,线程主动让出控制(可以调用time.sleep(0))。

4,把线程设置为睡眠状态。

5,解锁GIL.

6,再次重复以上步骤。

GIL的特性,也就导致了python不能充分利用多核cpu。而对面向I/O的(会调用内建操作系统C代码的)程序来说,GIL会在这个I/O调用之前被释放,以允许其他线程在这个线程等待I/O的时候运行。如果线程并为使用很多I/O操作,它会在自己的时间片一直占用处理器和GIL。这也就是所说的:I/O密集型python程序比计算密集型的程序更能充分利用多线程的好处。

总之,不要使用python多线程,使用python多进程进行并发编程,就不会有GIL这种问题存在,并且也能充分利用多核cpu。


一,提供的功能

提供了多线程和多进程的并发功能

二,基本方法

class   concurrent.futures.Executor (注:Executor为ThreadPoolExecutor或者ProcessPoolExecutor)

提供的方法如下:

    submit(fn, *args, **kwargs)

    fn:为需要异步执行的函数

    args,kwargs:为给函数传递的参数

    例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/env python
#coding:utf-8
import  time,re
import  os,datetime
from  concurrent  import  futures
def  wait_on_b():
     print  5
     time.sleep( 2 )
def  wait_on_a():
     print  6
     time.sleep( 2 )
ex  =  futures.ThreadPoolExecutor(max_workers = 2 )
ex.submit(wait_on_b)
ex.submit(wait_on_a)

wait_on_a和wait_on_b函数会同时执行,因为使用了2个worker

#####################################

    map(func, *iterables, timeout=None)

    此map函数和python自带的map函数功能类似,只不过concurrent模块的map函数从迭代器获得参数后异步执行。并且,每一个异步操作,能用timeout参数来设置超时时间,timeout的值可以是int或float型,如果操作timeout的话,会raisesTimeoutError。如果timeout参数不指定的话,则不设置超时间。

    func:为需要异步执行的函数

    iterables:可以是一个能迭代的对象,例如列表等。每一次func执行,会从iterables中取参数。

    timeout:设置每次异步操作的超时时间

    例:

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/env python
#coding:utf-8
import  time,re
import  os,datetime
from  concurrent  import  futures
data  =  [ '1' , '2' ]
def  wait_on(argument):
     print  argument
     time.sleep( 2 )
     return  'ok'
ex  =  futures.ThreadPoolExecutor(max_workers = 2 )
for  in  ex. map (wait_on,data):
     print  i

map函数异步执行完成之后,结果也是list,数据需要从list中取出

######################################

submit函数和map函数,根据需要,选一个使用即可。

    shutdown(wait=True)

    此函数用于释放异步执行操作后的系统资源。

    If wait is True then this method will not return until all the pending futures are done executing and the resources associated with the executor have been freed. If wait is False then this method will return immediately and the resources associated with the executor will be freed when all pending futures are done executing. Regardless of the value of wait, the entire Python program will not exit until all pending futures are done executing.

You can avoid having to call this method explicitly if you use the with statement, which will shutdown the Executor (waiting as if Executor.shutdown() were called with wait set to True):

with ThreadPoolExecutor(max_workers=4) as e:
    e.submit(shutil.copy, 'src1.txt', 'dest1.txt')

三,完整的concurrent例子


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#!/bin/env python
#coding:utf-8
import  time,re,fcntl
import  os,datetime
from  concurrent  import  futures
count_list  =  list ()
MinuteNum  =  1
StartTime  =  datetime.datetime( 2014 4 16 19 31 0 484870 )
NowTime  =  datetime.datetime.now()
os.system( ':>new.txt' )
f_new  =  open ( 'new.txt' , 'a' )
def  test(CountTimeFormat):
     =  open ( 'push_slave.stdout' , 'r' )
     for  line  in  f.readlines():
         if  re.search(CountTimeFormat,line):
             #获得文件专用锁
             fcntl.flock(f_new, fcntl.LOCK_EX)
             f_new.writelines(line)
             f_new.flush()
             #释放文件锁
             fcntl.flock(f_new, fcntl.LOCK_UN)
             break
while  1 :
     AfterOneMinute  =  datetime.timedelta(minutes = MinuteNum)
     CountTime  =  AfterOneMinute + StartTime
     CountTimeFormat  =  CountTime.strftime( '%Y-%m-%d %H:%M' )
     MinuteNum  =  MinuteNum + 1
     count_list.append(CountTimeFormat)
     if  CountTimeFormat  = =  "2014-04-23 16:00" :
         break
def  exec_cmd():
     with futures.ProcessPoolExecutor(max_workers = 24 ) as executor:
         dict (( executor.submit(test, times), times)  for  times  in  count_list)
if  __name__  = =  '__main__' :
     exec_cmd()
     f_new.close()










本文转自 leejia1989 51CTO博客,原文链接:http://blog.51cto.com/leejia/1407249,如需转载请自行联系原作者
目录
相关文章
|
14天前
|
存储 开发者 Python
Python中的collections模块与UserDict:用户自定义字典详解
【4月更文挑战第2天】在Python中,`collections.UserDict`是用于创建自定义字典行为的基类,它提供了一个可扩展的接口。通过继承`UserDict`,可以轻松添加或修改字典功能,如在`__init__`和`__setitem__`等方法中插入自定义逻辑。使用`UserDict`有助于保持代码可读性和可维护性,而不是直接继承内置的`dict`。例如,可以创建一个`LoggingDict`类,在设置键值对时记录操作。这样,开发者可以根据具体需求定制字典行为,同时保持对字典内部管理的抽象。
|
16天前
|
存储 缓存 算法
Python中collections模块的deque双端队列:深入解析与应用
在Python的`collections`模块中,`deque`(双端队列)是一个线程安全、快速添加和删除元素的双端队列数据类型。它支持从队列的两端添加和弹出元素,提供了比列表更高的效率,特别是在处理大型数据集时。本文将详细解析`deque`的原理、使用方法以及它在各种场景中的应用。
|
1天前
|
Python
python学习14-模块与包
python学习14-模块与包
|
3天前
|
SQL 关系型数据库 数据库
Python中SQLite数据库操作详解:利用sqlite3模块
【4月更文挑战第13天】在Python编程中,SQLite数据库是一个轻量级的关系型数据库管理系统,它包含在一个单一的文件内,不需要一个单独的服务器进程或操作系统级别的配置。由于其简单易用和高效性,SQLite经常作为应用程序的本地数据库解决方案。Python的内置sqlite3模块提供了与SQLite数据库交互的接口,使得在Python中操作SQLite数据库变得非常容易。
|
8天前
|
索引 Python
「Python系列」Python operator模块、math模块
Python的`operator`模块提供了一系列内置的操作符函数,这些函数对应于Python语言中的内建操作符。使用`operator`模块可以使代码更加清晰和易读,同时也能提高性能,因为它通常比使用Python内建操作符更快。
25 0
|
12天前
|
数据采集 网络协议 API
python中其他网络相关的模块和库简介
【4月更文挑战第4天】Python网络编程有多个流行模块和库,如requests提供简洁的HTTP客户端API,支持多种HTTP方法和自动处理复杂功能;Scrapy是高效的网络爬虫框架,适用于数据挖掘和自动化测试;aiohttp基于asyncio的异步HTTP库,用于构建高性能Web应用;Twisted是事件驱动的网络引擎,支持多种协议和异步编程;Flask和Django分别是轻量级和全栈Web框架,方便构建不同规模的Web应用。这些工具使网络编程更简单和高效。
|
16天前
|
数据采集 数据挖掘 Python
Python中collections模块的Counter计数器:深入解析与应用
在Python的`collections`模块中,`Counter`是一个强大且实用的工具,它主要用于计数可哈希对象。无论是统计单词出现的频率,还是分析数据集中元素的分布情况,`Counter`都能提供快速且直观的结果。本文将深入解析`Counter`计数器的原理、用法以及它在实际应用中的价值。
|
17天前
|
Python
Python中的math和cmath模块:数学运算的得力助手
Python作为一种功能强大的编程语言,提供了丰富的数学运算功能。其中,math和cmath模块就是Python中用于数学运算的重要工具。math模块提供了基本的数学函数和常量,适用于实数运算;而cmath模块则提供了对复数运算的支持,使得Python在数学计算和工程应用中更加灵活和强大。
|
20天前
|
数据挖掘 Python
Python中的datetime模块:轻松拿捏时间操作
Python的`datetime`模块是处理日期和时间的核心工具,包括`date`、`time`、`datetime`、`timedelta`类。它可以创建、操作和格式化日期时间。
18 2
|
22天前
|
Python
Python random模块(获取随机数)常用方法和使用例子
`random`模块在Python中用于生成随机数。
19 0