![](/img/trans.png)
[英]How to await on the closing event of the fd assigned to loop.add_reader?
[英]What File Descriptor object does Python AsyncIO's loop.add_reader() expect?
我試圖了解如何在Python 3.4中使用新的AsyncIO功能,我正在努力使用event_loop.add_reader() 。 從我發現的有限討論看來,它看起來像是從單獨的進程中讀取標准而不是打開文件的內容。 真的嗎? 如果是這樣,似乎沒有AsyncIO特定的方式來集成標准文件IO,這也是真的嗎?
我一直在玩以下代碼。 以下輸出給出異常PermissionError: [Errno 1] Operation not permitted
從add_reader()
行觸發的/python3.4/selectors.py self._epoll.register(key.fd, epoll_events)
的第add_reader()
行操作下面
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)
的行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()
這些函數需要一個文件描述符,即操作系統使用的底層整數,而不是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上寫的內容。
你不能在本地文件上使用add_reader,因為:
但是,從技術上講,是的,您應該能夠執行異步文件系統的讀/寫,(幾乎)所有系統都具有用於在后台執行i / o的DMA機制。 不,本地i / o並不是真的很快,沒有人會想要它,CPU的速度比磁盤i / o快數百萬倍。
如果您想嘗試異步i / o,請查找aiofile或aiofiles
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.