我正在尝试了解如何在Python 3.4中使用新的AsyncIO功能,而我正在努力使用event_loop.add_reader()。从我发现的limited discussions开始,它看起来像是用于从单独的进程中读取标准而不是打开文件的内容。真的吗?如果是这样,似乎没有AsyncIO特定的方式来集成标准文件IO,这也是真的吗?
我一直在玩以下代码。以下输出提供了/python3.4/selectors.py PermissionError: [Errno 1] Operation not permitted
第399行的异常self._epoll.register(key.fd, epoll_events)
,该异常由add_reader()
行下面的<{p}}触发
import asyncio
import urllib.parse
import sys
import pdb
import os
def fileCallback(*args):
pdb.set_trace()
path = sys.argv[1]
loop = asyncio.get_event_loop()
#fd = os.open(path, os.O_RDONLY)
fd = open(path, 'r')
#data = fd.read()
#print(data)
#fd.close()
pdb.set_trace()
task = loop.add_reader(fd, fileCallback, fd)
loop.run_until_complete(task)
loop.close()
修改
对于那些寻找如何使用AsyncIO一次读取多个文件的例子的人,就像我好奇一样,这里有一个如何实现它的例子。秘密在yield from asyncio.sleep(0)
行。这实际上暂停了当前函数,将其放回事件循环队列中,在执行所有其他就绪函数后调用。确定功能是根据它们的安排方式准备好的。
import asyncio
@asyncio.coroutine
def read_section(file, length):
yield from asyncio.sleep(0)
return file.read(length)
@asyncio.coroutine
def read_file(path):
fd = open(path, 'r')
retVal = []
cnt = 0
while True:
cnt = cnt + 1
data = yield from read_section(fd, 102400)
print(path + ': ' + str(cnt) + ' - ' + str(len(data)))
if len(data) == 0:
break;
fd.close()
paths = ["loadme.txt", "loadme also.txt"]
loop = asyncio.get_event_loop()
tasks = []
for path in paths:
tasks.append(asyncio.async(read_file(path)))
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
答案 0 :(得分:8)
这些函数需要一个文件描述符,即操作系统使用的底层整数,而不是Python的文件对象。基于文件描述符的文件对象在fileno()
方法上返回该描述符,例如:
>>> sys.stderr.fileno()
2
在Unix中,文件描述符可以附加到文件或许多其他内容,包括其他进程。
编辑OP编辑:
正如评论中的Max所说,你不能在本地文件上使用epoll
(并且asyncio使用epoll
)。是的,那有点奇怪。但是,您可以在管道上使用它,例如:
import asyncio
import urllib.parse
import sys
import pdb
import os
def fileCallback(*args):
print("Received: " + sys.stdin.readline())
loop = asyncio.get_event_loop()
task = loop.add_reader(sys.stdin.fileno(), fileCallback)
loop.run_forever()
这将回应你在stdin上写的内容。
答案 1 :(得分:0)
您不能在本地文件上使用add_reader,因为:
但是,从技术上讲,是的,您应该能够执行异步文件系统的读/写操作,(几乎)所有系统都具有DMA机制,用于“在后台”执行i / o。而且,本地I / O的运行速度不是真的快,以至于没人愿意这么做,CPU的速度是磁盘I / O的数百万倍。
如果要尝试异步i / o,请查找aiofile或aiofiles