一:使用 asyncio处理并发

介绍 asyncio 包,这个包使用事件循环驱动的协程实现并发。这是 Python 中最大也是最具雄心壮志的库之一。

二:示例

  1)单任务协程处理和普通任务比较

#普通任务示例
# _*_ coding:utf-8 _*_
__author__ = "lixiang"
import asyncio
import time def hello():
count=0
while count<10:
print("before",count)
try: time.sleep(0.1)
count+=1
print("after",count)
except Exception as e:
print(e)
return count if __name__=="__main__":
start_time=time.time()
hello()
end_time=time.time()
print("cost time",end_time-start_time)

普通任务示例

#单任务协程示例
# _*_ coding:utf-8 _*_
__author__ = "lixiang"
import asyncio
import time
@asyncio.coroutine# 表示要协程处理
def hello():
count=0
while count<10:
print("before",count)
try:
#使用 yield from asyncio.sleep(1) 代替 time.sleep(1),
yield from asyncio.sleep(0.1)
count+=1
print("after",count)
except Exception as e:
print(e)
return count if __name__=="__main__":
start_time=time.time()
loop=asyncio.get_event_loop()
loop.run_until_complete(hello())
loop.close()
end_time=time.time()
print("cost time",end_time-start_time)

单任务协程示例

  两种方式处理结果处理时间都是1秒,此时协程并不能体现并发的优势

# _*_ coding:utf-8 _*_
__author__ = "lixiang"
import asyncio
import time
@asyncio.coroutine# 要协程处理
def hello():
count=0
while count<10:
print("before",count)
try:
#使用 yield from asyncio.sleep(0.1) 代替 time.sleep(0.1),这样的休眠不会阻塞事件循环
yield from asyncio.sleep(0.1)
count+=1
print("after",count)
except Exception as e:
print(e)
return count @asyncio.coroutine
def hello_welcome():
result=yield from hello()
print(result) if __name__=="__main__":
start_time=time.time()
loop=asyncio.get_event_loop()
loop.run_until_complete(hello_welcome())
loop.close()
end_time=time.time()
print("cost time",end_time-start_time)

通过一个协程直接调用另外一协程

  此时也没有显示协程优势

  2)两个任务协程比较

  上面示例,如果hello运行需要1秒,别外一个任务运行也需要1秒。

# _*_ coding:utf-8 _*_
__author__ = "lixiang"
import asyncio
import time
@asyncio.coroutine# 要协程处理
def hello():
count=0
while count<10:
print("before",count)
try:
#使用 yield from asyncio.sleep(0.1) 代替 time.sleep(0.1),这样的休眠不会阻塞事件循环
yield from asyncio.sleep(0.1)
count+=1
print("after",count)
except Exception as e:
print(e)
return count @asyncio.coroutine
def show_hello():
yield from asyncio.sleep(1)
return 666 @asyncio.coroutine
def hello_welcome():
"""
安排协程hello的运行时间,这个运行时候根据show_hello来定。
如果show_hello安排时间为0.5秒,hello时间为0.1秒,10次循环不能正常结束,
提示Task was destroyed but it is pending!
如果show_hello安排时间为1秒,hello时间为0.1秒,10次循环能正常结束,
任务提示:Task finished
"""
re1=asyncio.async(hello())
result=yield from show_hello()
print(re1)
print("result",result) if __name__=="__main__":
start_time=time.time()
loop=asyncio.get_event_loop()
loop.run_until_complete(hello_welcome())
loop.close()
end_time=time.time()
print("cost time",end_time-start_time) #测试结果显示只需要1秒,并发优势显示出来。
这里我们对hello进行协程运行时间安排。
安排协程hello的运行时间,这个运行时间根据show_hello来定。
如果show_hello安排时间为0.5秒,hello时间为0.1秒,10次循环不能正常结束,
提示Task was destroyed but it is pending!
如果show_hello安排时间为0.9秒,hello时间为0.1秒,10次循环能正常结束,
任务提示:Task finished

两个任务协程比较

#多任务
# _*_ coding:utf-8 _*_
__author__ = "lixiang"
import asyncio
import time
@asyncio.coroutine# 要协程处理
def hello():
count=0
while count<10:
print("before",count)
try:
#使用 yield from asyncio.sleep(.1) 代替 time.sleep(.1),这样的休眠不会阻塞事件循环
yield from asyncio.sleep(0.1)
count+=1
print("after",count)
except Exception as e:
print(e)
return count @asyncio.coroutine
def show_hello():
yield from asyncio.sleep(1)
return 666 @asyncio.coroutine
def show_hello2():
yield from asyncio.sleep(1)
return 777 @asyncio.coroutine
def hello_welcome():
"""
安排协程hello的运行时间,这个运行时候根据show_hello来定。
如果show_hello安排时间为0.5秒,hello时间为0.1秒,10次循环不能正常结束,
提示Task was destroyed but it is pending!
如果show_hello安排时间为0.9秒,hello时间为0.1秒,10次循环能正常结束,
任务提示:Task finished
"""
asyncio.async(show_hello2())
asyncio.async(hello())
result=yield from show_hello() print("result",result) if __name__=="__main__":
start_time=time.time()
loop=asyncio.get_event_loop()
loop.run_until_complete(hello_welcome())
loop.close()
end_time=time.time()
print("cost time",end_time-start_time)

多任务

    @asyncio.coroutine# 要协程处理
def hello():
count=0
while count<10:
print("before",count)
try:
#使用 yield from asyncio.sleep(.1) 代替 time.sleep(.1),这样的休眠不会阻塞事件循环
yield from asyncio.sleep(0.1)
count+=1
print("after",count)
yield from asyncio.sleep(0.1)
except Exception as e:
print(e)

如果 hello里面有两个yield,两者之间是顺序,机每次循环需要0.2

上面为了执行这些操作,必须排定协程的运行时间,然后使用 asyncio.Task 对象包装协
    程。对协程来说,获取 Task 对象有两种主要方式。

   asyncio.async(coro_or_future, *, loop=None)

  create_

  上面如果都是通过时间控制协程运行,那如果控制协程的时间怎么设定比较好了,

  时间短了其他协程任务不能运行结束Task was destroyed but it is pending,时间设置长又会耗时长了。
     可以通过asyncio.wait解决
       asyncio.wait(...) 协程的参数是一个由期物或协程构成的可迭代对象; wait 会分别
       把各个协程包装进一个 Task 对象。最终的结果是, wait 处理的所有对象都通过某种方
      式变成 Future 类的实例。 wait 是协程函数,因此返回的是一个协程或生成器对
      象; wait_coro 变量中存储的正是这种对象。为了驱动协程,我们把协程传给
      loop.run_until_complete(...) 方法。虽然函数的名称是 wait,但它不是阻塞型函数。

   wait 是一个协程,等传给它的所有协程运行完毕后结束(这是 wait 函数的默认行为;参见这个示例后面的说明)
    loop.run_until_complete 方法的参数是一个期物或协程。如果是协
    程, run_until_complete 方法与 wait 函数一样,把协程包装进一个 Task 对象中。协
    程、期物和任务都能由 yield from 驱动,这正是 run_until_complete 方法对 wait
    函数返回的 wait_coro 对象所做的事。 wait_coro 运行结束后返回一个元组,第一个元
    素是一系列结束的期物,第二个元素是一系列未结束的期物

    # _*_ coding:utf-8 _*_
__author__ = "lixiang"
import asyncio
import time
@asyncio.coroutine# 要协程处理
def hello():
count=0
while count<10:
print("before",count)
try:
#使用 yield from asyncio.sleep(.1) 代替 time.sleep(.1),这样的休眠不会阻塞事件循环
yield from asyncio.sleep(0.1)
count+=1
print("after",count)
yield from asyncio.sleep(0.1)
except Exception as e:
print(e)
return count @asyncio.coroutine
def show_hello():
yield from asyncio.sleep(1.2)
return 666 @asyncio.coroutine
def show_hello2():
yield from asyncio.sleep(1.2)
return 777 # @asyncio.coroutine
# def hello_welcome():
# """
# 安排协程hello的运行时间,这个运行时候根据show_hello来定。
# 如果show_hello安排时间为0.5秒,hello时间为0.1秒,10次循环不能正常结束,
# 提示Task was destroyed but it is pending!
# 如果show_hello安排时间为0.9秒,hello时间为0.1秒,10次循环能正常结束,
# 任务提示:Task finished
# """
# asyncio.async(show_hello2())
# asyncio.async(hello())
# result=yield from show_hello()
#
# print("result",result) if __name__=="__main__":
start_time=time.time()
loop=asyncio.get_event_loop()
wait_coro=asyncio.wait([hello(),show_hello(),show_hello2()])
loop.run_until_complete(wait_coro)
wait_coro.close()
loop.close()
end_time=time.time()
print("cost time",end_time-start_time)

asyncio wait使用

#如果要实时显示那个协程已完成了
    我把一个协程列表传给 asyncio.wait 函数,经由
    loop.run_until_complete 方法驱动,全部协程运行完毕后,这个函数会返回所有下载
    结果。可是,为了更新进度条,各个协程运行结束后就要立即获取结果。在线程池版示例
    中(见示例 17-14),为了集成进度条,我们使用的是 as_completed 生成器函数;幸
    好, asyncio 包提供了这个生成器函数的相应版本

# _*_ coding:utf-8 _*_
__author__ = "lixiang"
import asyncio
import time
@asyncio.coroutine# 要协程处理
def hello():
count=0
while count<10:
print("before",count)
try:
#使用 yield from asyncio.sleep(.1) 代替 time.sleep(.1),这样的休眠不会阻塞事件循环
yield from asyncio.sleep(0.1)
count+=1
print("after",count)
yield from asyncio.sleep(0.1)
except Exception as e:
print(e)
return count @asyncio.coroutine
def show_hello():
yield from asyncio.sleep(1.2)
return 666 @asyncio.coroutine
def show_hello2():
yield from asyncio.sleep(1.3)
return 777 @asyncio.coroutine
def hello_welcome():
count=0
coro=asyncio.as_completed([hello(),show_hello(),show_hello2()]) for future in coro:
res=yield from future
print("",res)
count+=1
print(count)#可以在这里实现进度条功能
return count if __name__=="__main__":
start_time=time.time()
loop=asyncio.get_event_loop()
counts=loop.run_until_complete(hello_welcome())
print(counts)
loop.close()
end_time=time.time()
print("cost time",end_time-start_time)

asyncio as_complated

6)协程三( asyncio处理并发)的更多相关文章

  1. python并发编程之asyncio协程(三)

    协程实现了在单线程下的并发,每个协程共享线程的几乎所有的资源,除了协程自己私有的上下文栈:协程的切换属于程序级别的切换,对于操作系统来说是无感知的,因此切换速度更快.开销更小.效率更高,在有多IO操作 ...

  2. Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就绪,挂起,运行) ,***协程概念,yield模拟并发(有缺陷),Greenlet模块(手动切换),Gevent(协程并发)

    Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就 ...

  3. 【python】-- 协程介绍及基本示例、协程遇到IO操作自动切换、协程(gevent)并发爬网页

    协程介绍及基本示例 协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是协程:协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他 ...

  4. 一个有趣的小例子,带你入门协程模块-asyncio

    一个有趣的小例子,带你入门协程模块-asyncio 上篇文章写了关于yield from的用法,简单的了解异步模式,[https://www.cnblogs.com/c-x-a/p/10106031. ...

  5. Python协程与asyncio

    asyncio(解决异步io编程的一整套解决方案,它主要用于异步网络操作.并发和协程)协程(Coroutine一种用户态的轻量级微线程,它是程序级别的,在执行过程中可以中断去执行其它的子程序,别的子程 ...

  6. Kotlin Coroutine(协程): 三、了解协程

    @ 目录 前言 一.协程上下文 1.调度器 2.给协程起名 3.局部变量 二.启动模式 CoroutineStart 三.异常处理 1.异常测试 2.CoroutineExceptionHandler ...

  7. 协程+IO切换实现并发

    from gevent import monkey # 以后代码中遇到IO都会自动执行greenlet的switch进行切换 monkey.patch_all() import requests im ...

  8. 利用协程和socket实现并发

    服务端代码 from gevent import monkey monkey.patch_all() from gevent import spawn import socket def commun ...

  9. python协程--asyncio模块(基础并发测试)

    在高并发的场景下,python提供了一个多线程的模块threading,但似乎这个模块并不近人如意,原因在于cpython本身的全局解析锁(GIL)问题,在一段时间片内实际上的执行是单线程的.同时还存 ...

随机推荐

  1. MyEclipse创建SWT程序

    创建项目:NewProject->WindowsBuilder->SWT Designer->SWT/JFACE Java Project添加SWT窗口:New->Window ...

  2. 使用phpexcel上传下载excel文件

    1. 下载 <?php /** * Created by lonm.shi. * Date: 2012-02-09 * Time: 下午4:54 * To change this templat ...

  3. 虚拟机中Linux安装(转)

    地址:http://blog.csdn.net/u013142781/article/details/50529030 不是每一个程序员都必须玩过linux,只是博主觉得现在的很多服务器都是linux ...

  4. [C++]Linux之进程间通信小结【待完善】

    [此博文,待日后完善] 进程通信方式: 1.管道通信(匿名管道/命名管道) 2.消息队列 3.共享内存 4.信号量 1.管道通信 无名管道用于具有亲缘关系进程间的通信管道是半双工的,数据只能单向流动( ...

  5. Codeforces 1065F(树形dp)

    题目链接 题意 给一棵树,进行如下操作,如果当前点非叶子,则往子树移动,否则最多向上移动k次,问从根节点开始最多访问多少叶子 思路 预处理出每个点最多能“白嫖”到几个叶子,根据下一个点的状态更新最优方 ...

  6. luogu P3297 [SDOI2013]逃考

    传送门 gugugu 首先每个人管理的区域是一个多边形,并且整个矩形是被这样的多边形填满的.现在的问题是求一条经过多边形最少的路径到达边界,这个可以最短路. 现在的问题是建图,显然我们应该给相邻的多边 ...

  7. Elasticsearch 5.0 —— Head插件部署指南(Head目前支持5.0了!请不要看本篇文章了)

    使用ES的基本都会使用过head,但是版本升级到5.0后,head插件就不好使了.下面就看看如何在5.0中启动Head插件吧! Head目前支持5.0了!请不要看本篇文章了 Head目前支持5.0了! ...

  8. Hbase思维导图之架构

  9. Spark思维导图之Spark Core

  10. 5.22 css和基本选择器

    1,css的三种引入方式 1,行内样式 2,内接样式 3,外接样式:链接式和导入式. HTML的缺陷: 不能够适应多种设备 要求浏览器必须智能化足够庞大 数据和显示没有分开 功能不够强大 CSS 优点 ...