导航:首页 > 编程语言 > 异步通信python

异步通信python

发布时间:2023-02-24 03:29:37

python网络编程基础的作品目录

关于作者
关于技术审校
致谢
简介
第1部分 底层网络
第1章 客户/服务器网络介绍
第2章 网络客户端
第3章 网络服务器
第4章 域名系统
第5章 域名系统
第2部分 Web Service
第6章 Web客户端访问
第7章 解析HTML和XHTML
第8章 XML和XML-RPC
第3部分 E-mail服务
第9章 E-mail的编写和编码
第10章 简单邮件传输协议(SMTP)
第11章 POP
第12章 IMAP
第4部分 多用途的客户端协议
第13章 FTP
第14章 数据库客户端
第15章 SSL
第5部分 服务器端框架
第16章 SocketSever
第17章 SimpleXMLRPCServer
第18章 CGI
第19章 Mod_python
第6部分 多任务处理
第20章 forking
第21章 线程
第22章 异步通信
索引

Ⅱ python异步有哪些方式

yield相当于return,他将相应的值返回给调用next()或者send()的调用者,从而交出了CPU使用权,而当调用者再次调用next()或者send()的时候,又会返回到yield中断的地方,如果send有参数,还会将参数返回给yield赋值的变量,如果没有就和next()一样赋值为None。但是这里会遇到一个问题,就是嵌套使用generator时外层的generator需要写大量代码,看如下示例:
注意以下代码均在Python3.6上运行调试

#!/usr/bin/env python# encoding:utf-8def inner_generator():
i = 0
while True:
i = yield i if i > 10: raise StopIterationdef outer_generator():
print("do something before yield")
from_inner = 0
from_outer = 1
g = inner_generator()
g.send(None) while 1: try:
from_inner = g.send(from_outer)
from_outer = yield from_inner except StopIteration: breakdef main():
g = outer_generator()
g.send(None)
i = 0
while 1: try:
i = g.send(i + 1)
print(i) except StopIteration: breakif __name__ == '__main__':
main()041

为了简化,在Python3.3中引入了yield from

yield from

使用yield from有两个好处,

1、可以将main中send的参数一直返回给最里层的generator,
2、同时我们也不需要再使用while循环和send (), next()来进行迭代。

我们可以将上边的代码修改如下:

def inner_generator():
i = 0
while True:
i = yield i if i > 10: raise StopIterationdef outer_generator():
print("do something before coroutine start") yield from inner_generator()def main():
g = outer_generator()
g.send(None)
i = 0
while 1: try:
i = g.send(i + 1)
print(i) except StopIteration: breakif __name__ == '__main__':
main()

执行结果如下:

do something before coroutine start123456789101234567891011

这里inner_generator()中执行的代码片段我们实际就可以认为是协程,所以总的来说逻辑图如下:

我们都知道Python由于GIL(Global Interpreter Lock)原因,其线程效率并不高,并且在*nix系统中,创建线程的开销并不比进程小,因此在并发操作时,多线程的效率还是受到了很大制约的。所以后来人们发现通过yield来中断代码片段的执行,同时交出了cpu的使用权,于是协程的概念产生了。在Python3.4正式引入了协程的概念,代码示例如下:

import asyncio# Borrowed from http://curio.readthedocs.org/en/latest/[email protected] countdown(number, n):
while n > 0:
print('T-minus', n, '({})'.format(number)) yield from asyncio.sleep(1)
n -= 1loop = asyncio.get_event_loop()
tasks = [
asyncio.ensure_future(countdown("A", 2)),
asyncio.ensure_future(countdown("B", 3))]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()12345678910111213141516

示例显示了在Python3.4引入两个重要概念协程和事件循环,
通过修饰符@asyncio.coroutine定义了一个协程,而通过event loop来执行tasks中所有的协程任务。之后在Python3.5引入了新的async & await语法,从而有了原生协程的概念。

async & await

在Python3.5中,引入了aync&await 语法结构,通过”aync def”可以定义一个协程代码片段,作用类似于Python3.4中的@asyncio.coroutine修饰符,而await则相当于”yield from”。

先来看一段代码,这个是我刚开始使用async&await语法时,写的一段小程序。

#!/usr/bin/env python# encoding:utf-8import asyncioimport requestsimport time


async def wait_download(url):
response = await requets.get(url)
print("get {} response complete.".format(url))


async def main():
start = time.time()
await asyncio.wait([
wait_download("http://www.163.com"),
wait_download("http://www.mi.com"),
wait_download("http://www.google.com")])
end = time.time()
print("Complete in {} seconds".format(end - start))


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

这里会收到这样的报错:

Task exception was never retrieved
future: <Task finished coro=<wait_download() done, defined at asynctest.py:9> exception=TypeError("object Response can't be used in 'await' expression",)>
Traceback (most recent call last):
File "asynctest.py", line 10, in wait_download
data = await requests.get(url)
TypeError: object Response can't be used in 'await' expression123456

这是由于requests.get()函数返回的Response对象不能用于await表达式,可是如果不能用于await,还怎么样来实现异步呢?
原来Python的await表达式是类似于”yield from”的东西,但是await会去做参数检查,它要求await表达式中的对象必须是awaitable的,那啥是awaitable呢? awaitable对象必须满足如下条件中其中之一:

1、A native coroutine object returned from a native coroutine function .

原生协程对象

2、A generator-based coroutine object returned from a function decorated with types.coroutine() .

types.coroutine()修饰的基于生成器的协程对象,注意不是Python3.4中asyncio.coroutine

3、An object with an await method returning an iterator.

实现了await method,并在其中返回了iterator的对象

根据这些条件定义,我们可以修改代码如下:

#!/usr/bin/env python# encoding:utf-8import asyncioimport requestsimport time


async def download(url): # 通过async def定义的函数是原生的协程对象
response = requests.get(url)
print(response.text)


async def wait_download(url):
await download(url) # 这里download(url)就是一个原生的协程对象
print("get {} data complete.".format(url))


async def main():
start = time.time()
await asyncio.wait([
wait_download("http://www.163.com"),
wait_download("http://www.mi.com"),
wait_download("http://www.google.com")])
end = time.time()
print("Complete in {} seconds".format(end - start))


loop = asyncio.get_event_loop()
loop.run_until_complete(main())27282930

好了现在一个真正的实现了异步编程的小程序终于诞生了。
而目前更牛逼的异步是使用uvloop或者pyuv,这两个最新的Python库都是libuv实现的,可以提供更加高效的event loop。

uvloop和pyuv

pyuv实现了Python2.x和3.x,但是该项目在github上已经许久没有更新了,不知道是否还有人在维护。
uvloop只实现了3.x, 但是该项目在github上始终活跃。

它们的使用也非常简单,以uvloop为例,只需要添加以下代码就可以了

import asyncioimport uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())123

Ⅲ python2.7怎么实现异步

改进之前
之前,我的查询步骤很简单,就是:
前端提交查询请求 --> 建立数据库连接 --> 新建游标 --> 执行命令 --> 接受结果 --> 关闭游标、连接
这几大步骤的顺序执行。
这里面当然问题很大:
建立数据库连接实际上就是新建一个套接字。这是进程间通信的几种方法里,开销最大的了。
在“执行命令”和“接受结果”两个步骤中,线程在阻塞在数据库内部的运行过程中,数据库连接和游标都处于闲置状态。
这样一来,每一次查询都要顺序的新建数据库连接,都要阻塞在数据库返回结果的过程中。当前端提交大量查询请求时,查询效率肯定是很低的。
第一次改进
之前的模块里,问题最大的就是第一步——建立数据库连接套接字了。如果能够一次性建立连接,之后查询能够反复服用这个连接就好了。
所以,首先应该把数据库查询模块作为一个单独的守护进程去执行,而前端app作为主进程响应用户的点击操作。那么两条进程怎么传递消息呢?翻了几天Python文档,终于构思出来:用队列queue作为生产者(web前端)向消费者(数据库后端)传递任务的渠道。生产者,会与SQL命令一起,同时传递一个管道pipe的连接对象,作为任务完成后,回传结果的渠道。确保,任务的接收方与发送方保持一致。
作为第二个问题的解决方法,可以使用线程池来并发获取任务队列中的task,然后执行命令并回传结果。
第二次改进
第一次改进的效果还是很明显的,不用任何测试手段。直接点击页面链接,可以很直观地感觉到反应速度有很明显的加快。
但是对于第二个问题,使用线程池还是有些欠妥当。因为,CPython解释器存在GIL问题,所有线程实际上都在一个解释器进程里调度。线程稍微开多一点,解释器进程就会频繁的切换线程,而线程切换的开销也不小。线程多一点,甚至会出现“抖动”问题(也就是刚刚唤醒一个线程,就进入挂起状态,刚刚换到栈帧或内存的上下文,又被换回内存或者磁盘),效率大大降低。也就是说,线程池的并发量很有限。
试过了多进程、多线程,只能在单个线程里做文章了。
Python中的asyncio库
Python里有大量的协程库可以实现单线程内的并发操作,比如Twisted、Gevent等等。Python官方在3.5版本里提供了asyncio库同样可以实现协程并发。asyncio库大大降低了Python中协程的实现难度,就像定义普通函数那样就可以了,只是要在def前面多加一个async关键词。async def函数中,需要阻塞在其他async def函数的位置前面可以加上await关键词。
import asyncio
async def wait():
await asyncio.sleep(2)
async def execute(task):
process_task(task)
await wait()
continue_job()
async def函数的执行稍微麻烦点。需要首先获取一个loop对象,然后由这个对象代为执行async def函数。
loop = asyncio.get_event_loop()
loop.run_until_complete(execute(task))
loop.close()
loop在执行execute(task)函数时,如果遇到await关键字,就会暂时挂起当前协程,转而去执行其他阻塞在await关键词的协程,从而实现协程并发。
不过需要注意的是,run_until_complete()函数本身是一个阻塞函数。也就是说,当前线程会等候一个run_until_complete()函数执行完毕之后,才会继续执行下一部函数。所以下面这段代码并不能并发执行。
for task in task_list:
loop.run_until_complete(task)
对与这个问题,asyncio库也有相应的解决方案:gather函数。
loop = asyncio.get_event_loop()
tasks = [asyncio.ensure_future(execute(task))
for task in task_list]
loop.run_until_complete(asyncio.gather(*tasks))
loop.close()
当然了,async def函数的执行并不只有这两种解决方案,还有call_soon与run_forever的配合执行等等,更多内容还请参考官方文档。
Python下的I/O多路复用
协程,实际上,也存在上下文切换,只不过开销很轻微。而I/O多路复用则完全不存在这个问题。
目前,Linux上比较火的I/O多路复用API要算epoll了。Tornado,就是通过调用C语言封装的epoll库,成功解决了C10K问题(当然还有Pypy的功劳)。
在Linux里查文档,可以看到epoll只有三类函数,调用起来比较方便易懂。
创建epoll对象,并返回其对应的文件描述符(file descriptor)。
int epoll_create(int size);
int epoll_create1(int flags);
控制监听事件。第一个参数epfd就对应于前面命令创建的epoll对象的文件描述符;第二个参数表示该命令要执行的动作:监听事件的新增、修改或者删除;第三个参数,是要监听的文件对应的描述符;第四个,代表要监听的事件。
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
等候。这是一个阻塞函数,调用者会等候内核通知所注册的事件被触发。
int epoll_wait(int epfd, struct epoll_event *events,
int maxevents, int timeout);
int epoll_pwait(int epfd, struct epoll_event *events,
int maxevents, int timeout,
const sigset_t *sigmask);
在Python的select库里:
select.epoll()对应于第一类创建函数;
epoll.register(),epoll.unregister(),epoll.modify()均是对控制函数epoll_ctl的封装;
epoll.poll()则是对等候函数epoll_wait的封装。
Python里epoll相关API的最大问题应该是在epoll.poll()。相比于其所封装的epoll_wait,用户无法手动指定要等候的事件,也就是后者的第二个参数struct epoll_event *events。没法实现精确控制。因此只能使用替代方案:select.select()函数。
根据Python官方文档,select.select(rlist, wlist, xlist[, timeout])是对Unix系统中select函数的直接调用,与C语言API的传参很接近。前三个参数都是列表,其中的元素都是要注册到内核的文件描述符。如果想用自定义类,就要确保实现了fileno()方法。
其分别对应于:
rlist: 等候直到可读
wlist: 等候直到可写
xlist: 等候直到异常。这个异常的定义,要查看系统文档。
select.select(),类似于epoll.poll(),先注册文件和事件,然后保持等候内核通知,是阻塞函数。
实际应用
Psycopg2库支持对异步和协程,但和一般情况下的用法略有区别。普通数据库连接支持不同线程中的不同游标并发查询;而异步连接则不支持不同游标的同时查询。所以异步连接的不同游标之间必须使用I/O复用方法来协调调度。
所以,我的大致实现思路是这样的:首先并发执行大量协程,从任务队列中提取任务,再向连接池请求连接,创建游标,然后执行命令,并返回结果。在获取游标和接受查询结果之前,均要阻塞等候内核通知连接可用。
其中,连接池返回连接时,会根据引用连接的协程数量,返回负载最轻的连接。这也是自己定义AsyncConnectionPool类的目的。
我的代码位于:bottle-blog/dbservice.py
存在问题
当然了,这个流程目前还一些问题。
首先就是每次轮询拿到任务之后,都会走这么一个流程。
获取连接 --> 新建游标 --> 执行任务 --> 关闭游标 --> 取消连接引用
本来,最好的情况应该是:在轮询之前,就建好游标;在轮询时,直接等候内核通知,执行相应任务。这样可以减少轮询时的任务量。但是如果协程提前对应好连接,那就不能保证在获取任务时,保持各连接负载均衡了。
所以这一块,还有工作要做。
还有就是epoll没能用上,有些遗憾。
以后打算写点C语言的内容,或者用Python/C API,或者用Ctypes包装共享库,来实现epoll的调用。
最后,请允许我吐槽一下Python的epoll相关文档:简直太弱了!!!必须看源码才能弄清楚功能。

Ⅳ Python标准库的主要功能有哪些

Python常用库大全,看看有没有你需要的。

环境管理
管理 Python 版本和环境的工具
p – 非常简单的交互式 python 版本管理工具。
pyenv – 简单的 Python 版本管理工具。
Vex – 可以在虚拟环境中执行命令。
virtualenv – 创建独立 Python 环境的工具。
virtualenvwrapper- virtualenv 的一组扩展。
包管理
管理包和依赖的工具。
pip – Python 包和依赖关系管理工具。
pip-tools – 保证 Python 包依赖关系更新的一组工具。
conda – 跨平台,Python 二进制包管理工具。
Curdling – 管理 Python 包的命令行工具。
wheel – Python 分发的新标准,意在取代 eggs。
包仓库
本地 PyPI 仓库服务和代理。
warehouse – 下一代 PyPI。
Warehousebandersnatch – PyPA 提供的 PyPI 镜像工具。
devpi – PyPI 服务和打包/测试/分发工具。
localshop – 本地 PyPI 服务(自定义包并且自动对 PyPI 镜像)。
分发
打包为可执行文件以便分发。
PyInstaller – 将 Python 程序转换成独立的执行文件(跨平台)。
dh-virtualenv – 构建并将 virtualenv 虚拟环境作为一个 Debian 包来发布。
Nuitka – 将脚本、模块、包编译成可执行文件或扩展模块。
py2app – 将 Python 脚本变为独立软件包(Mac OS X)。
py2exe – 将 Python 脚本变为独立软件包(Windows)。
pynsist – 一个用来创建 Windows 安装程序的工具,可以在安装程序中打包 Python本身。
构建工具
将源码编译成软件。
buildout – 一个构建系统,从多个组件来创建,组装和部署应用。
BitBake – 针对嵌入式 Linux 的类似 make 的构建工具。
fabricate – 对任何语言自动找到依赖关系的构建工具。
PlatformIO – 多平台命令行构建工具。
PyBuilder – 纯 Python 实现的持续化构建工具。
SCons – 软件构建工具。
交互式解析器
交互式 Python 解析器。
IPython – 功能丰富的工具,非常有效的使用交互式 Python。
bpython- 界面丰富的 Python 解析器。
ptpython – 高级交互式Python解析器, 构建于python-prompt-toolkit 之上。
文件
文件管理和 MIME(多用途的网际邮件扩充协议)类型检测。
imghdr – (Python 标准库)检测图片类型。
mimetypes – (Python 标准库)将文件名映射为 MIME 类型。
path.py – 对 os.path 进行封装的模块。
pathlib – (Python3.4+ 标准库)跨平台的、面向对象的路径操作库。
python-magic- 文件类型检测的第三方库 libmagic 的 Python 接口。
Unipath- 用面向对象的方式操作文件和目录
watchdog – 管理文件系统事件的 API 和 shell 工具
日期和时间
操作日期和时间的类库。
arrow- 更好的 Python 日期时间操作类库。
Chronyk – Python 3 的类库,用于解析手写格式的时间和日期。
dateutil – Python datetime 模块的扩展。
delorean- 解决 Python 中有关日期处理的棘手问题的库。
moment – 一个用来处理时间和日期的Python库。灵感来自于Moment.js。
PyTime – 一个简单易用的Python模块,用于通过字符串来操作日期/时间。
pytz – 现代以及历史版本的世界时区定义。将时区数据库引入Python。
when.py – 提供用户友好的函数来帮助用户进行常用的日期和时间操作。
文本处理
用于解析和操作文本的库。
通用
chardet – 字符编码检测器,兼容 Python2 和 Python3。
difflib – (Python 标准库)帮助我们进行差异化比较。
ftfy – 让Unicode文本更完整更连贯。
fuzzywuzzy – 模糊字符串匹配。
Levenshtein – 快速计算编辑距离以及字符串的相似度。
pangu.py – 在中日韩语字符和数字字母之间添加空格。
pyfiglet -figlet 的 Python实现。
shortuuid – 一个生成器库,用以生成简洁的,明白的,URL 安全的 UUID。
unidecode – Unicode 文本的 ASCII 转换形式 。
uniout – 打印可读的字符,而不是转义的字符串。
xpinyin – 一个用于把汉字转换为拼音的库。

Ⅳ python 什么是异步通信


Ⅵ Python中的并行和并发是什么

并行和并发

无论是并行还是并发,在用户看来都是'同时'运行的,不管是进程还是线程,都只是一个任务而已,真是干活的是cpu,cpu来做这些任务,而一个cpu同一时刻只能执行一个任务。

并发是伪并行,即看起来是同时运行。单个cpu+多道技术就可以实现并发,(并行也属于并发),简单的可以理解为快速在多个线程来回切换,感觉好像同时在做多个事情。

只有具备多个cpu才能实现并行,单核下,可以利用多道技术,多个核,每个核也都可以利用多道技术(多道技术是针对单核而言的)。 有四个核,六个任务,这样同一时间有四个任务被执行,假设分别被分配给了cpu1,cpu2,cpu3,cpu4,一旦任务1遇到I/O就被迫中断执行,此时任务5就拿到cpu1的时间片去执行,这就是单核下的多道技术 ,而一旦任务1的I/O结束了,操作系统会重新调用它(需知进程的调度、分配给哪个cpu运行,由操作系统说了算),可能被分配给四个cpu中的任意一个去执行。

相关推荐:《Python视频教程》

多道技术:内存中同时存入多道(多个)程序,cpu从一个进程快速切换到另外一个,使每个进程各自运行几十或几百毫秒,这样,虽然在某一个瞬间,一个cpu只能执行一个任务,但在1秒内,cpu却可以运行多个进程,这就给人产生了并行的错觉,即伪并发,以此来区分多处理器操作系统的真正硬件并行(多个cpu共享同一个物理内存)。

同步执行:一个进程在执行某个任务时,另外一个进程必须等待其执行完毕,才能继续执行。

异步执行:一个进程在执行某个任务时,另外一个进程无需等待其执行完毕,就可以继续执行,当有消息返回时,系统会通知后者进行处理,这样可以提高执行效率。

举个例子,打电话时就是同步通信,发短息时就是异步通信。

相关推荐:

Python如何实现线程间同步

Ⅶ 用 Python 可以来做什么

Web 和 Internet开发;科学计算和统计;人工智能;桌面界面开发;软件开发;后端开发;网络接口:能方便进行系统维护和管理,Linux下标志性语言之一,是很多系统管理员理想的编程工具。

Python的设计目标之一是让代码具备高度的可阅读性。它设计时尽量使用其它语言经常使用的标点符号和英文单字,让代码看起来整洁美观。它不像其他的静态语言如C、Pascal那样需要重复书写声明语句,也不像它们的语法那样经常有特殊情况和意外。

Python标准库的主要功能有:

1、文本处理,包含文本格式化、正则表达式匹配、文本差异计算与合并、Unicode支持,二进制数据处理等功能

2、文件处理,包含文件操作、创建临时文件、文件压缩与归档、操作配置文件等功能

3、操作系统功能,包含线程与进程支持、IO复用、日期与时间处理、调用系统函数、写日记(logging)等功能

4、网络通信,包含网络套接字,SSL加密通信、异步网络通信等功能

5、网络协议,支持HTTP,FTP,SMTP,POP,IMAP,NNTP,XMLRPC等多种网络协议,并提供了编写网络服务器的框架

6、W3C格式支持,包含HTML,SGML,XML的处理

7、其它功能,包括国际化支持、数学运算、HASH、Tkinter等

阅读全文

与异步通信python相关的资料

热点内容
初二多项式乘法速算法 浏览:455
android多个布局文件 浏览:629
奔跑程序员 浏览:468
服务器如何搭建类似github 浏览:292
明日之后安卓太卡怎么办 浏览:502
如何使用命令方块找到村庄 浏览:766
泛函压缩映像原理 浏览:521
win10清除文件夹浏览记录 浏览:964
如何查看服务器域中所有服务 浏览:384
学mastercam91编程要多久 浏览:999
如何查服务器地址和端口 浏览:911
教学云平台app怎么下载 浏览:389
单片机510教学视频 浏览:624
陕西信合app怎么查看自己的存款 浏览:663
风冷冰箱有压缩机 浏览:274
android实现wifi连接wifi 浏览:669
飞猪app怎么帮别人值机 浏览:924
笔记本开我的世界服务器地址 浏览:546
怎样隐藏bat命令 浏览:127
android开发创意 浏览:138