Python 用于文件写入的Asyncio
我刚刚读完了RealPython的两个Asyncio教程,其中解释了Asyncio(和线程)对于I/O绑定的进程非常有用。本教程主要使用asyncio.sleep()和aiohttps模块的asynchronous session.get(url)函数来表示我们希望在其他任务运行时将控制权传递回其他任务的I/O“工作” 我看到I/O被绑定,并考虑尝试编写大型ish文件,其目的是通过异步而不是同步运行来减少编写10个大型文件所需的时间,因为在编写每个文件时,我们都要等待。我认为这就像从文件系统上下文中的session.get(url)获取响应一样。但是,与同步写入文件相比,我似乎无法获得任何性能优势,因此我要么错误地实现了异步文件写入(使用aiofile),或者我误解了某些文件写入不能异步实现的事情——我的第一个猜测是,有一个最大的文件写入速度/容量,并且在执行第一个任务时已经达到了这个速度/容量。第三种可能性是,它实现正确,但在这种情况下,它的时间恰好比同步实现要长,但我发现这不太可能 下面是我为比较编写大型文件的同步和异步实现而编写的代码。任何解释我在实现或理解上哪里出了错的帮助都将是令人惊讶的 进口Python 用于文件写入的Asyncio,python,python-asyncio,Python,Python Asyncio,我刚刚读完了RealPython的两个Asyncio教程,其中解释了Asyncio(和线程)对于I/O绑定的进程非常有用。本教程主要使用asyncio.sleep()和aiohttps模块的asynchronous session.get(url)函数来表示我们希望在其他任务运行时将控制权传递回其他任务的I/O“工作” 我看到I/O被绑定,并考虑尝试编写大型ish文件,其目的是通过异步而不是同步运行来减少编写10个大型文件所需的时间,因为在编写每个文件时,我们都要等待。我认为这就像从文件系统上下
import asyncio
from aiofile import AIOFile
from codetiming import Timer
同步文件写入
def write_file(text):
with open('somefile.txt', 'w') as file:
print(f'Writing file {text[:20]}')
file.write(text)
def main_sync():
timer = Timer(text=f"Task elapsed time: {{:.1f}}")
timer.start()
for text in [
"http://google.com",
"http://yahoo.com",
"http://linkedin.com",
"http://apple.com",
"http://microsoft.com",
"http://facebook.com",
"http://twitter.com",
]:
print(f"Task writing file: {text[:20]}")
write_file(text*40000000)
timer.stop()
async def aio_file_write(text):
async with AIOFile("somefile.txt", 'w') as file:
print(f'Writing file {text[:20]}')
await file.write(text)
await file.fsync()
async def task(name, work_queue):
timer = Timer(text=f"Task {name} elapsed time: {{:.1f}}")
while not work_queue.empty():
text = await work_queue.get()
print(f"Task {name} writing file: {text[:20]}")
timer.start()
await aio_file_write(text)
timer.stop()
async def main():
work_queue = asyncio.Queue()
for text in [
"http://google.com",
"http://yahoo.com",
"http://linkedin.com",
"http://apple.com",
"http://microsoft.com",
"http://facebook.com",
"http://twitter.com",
]:
await work_queue.put(text*40000000)
with Timer(text="\nTotal elapsed time: {:.1f}"):
await asyncio.gather(
asyncio.create_task(task("One", work_queue)),
asyncio.create_task(task("Two", work_queue)),
)
异步文件写入
def write_file(text):
with open('somefile.txt', 'w') as file:
print(f'Writing file {text[:20]}')
file.write(text)
def main_sync():
timer = Timer(text=f"Task elapsed time: {{:.1f}}")
timer.start()
for text in [
"http://google.com",
"http://yahoo.com",
"http://linkedin.com",
"http://apple.com",
"http://microsoft.com",
"http://facebook.com",
"http://twitter.com",
]:
print(f"Task writing file: {text[:20]}")
write_file(text*40000000)
timer.stop()
async def aio_file_write(text):
async with AIOFile("somefile.txt", 'w') as file:
print(f'Writing file {text[:20]}')
await file.write(text)
await file.fsync()
async def task(name, work_queue):
timer = Timer(text=f"Task {name} elapsed time: {{:.1f}}")
while not work_queue.empty():
text = await work_queue.get()
print(f"Task {name} writing file: {text[:20]}")
timer.start()
await aio_file_write(text)
timer.stop()
async def main():
work_queue = asyncio.Queue()
for text in [
"http://google.com",
"http://yahoo.com",
"http://linkedin.com",
"http://apple.com",
"http://microsoft.com",
"http://facebook.com",
"http://twitter.com",
]:
await work_queue.put(text*40000000)
with Timer(text="\nTotal elapsed time: {:.1f}"):
await asyncio.gather(
asyncio.create_task(task("One", work_queue)),
asyncio.create_task(task("Two", work_queue)),
)
剧本
if __name__== "__main__":
asyncio.run(main())
else:
main_sync()
你说“这个想法是通过非同步运行来减少写10个大文件所需的时间”——这是行不通的。写入数据所需的时间将保持不变。您只能在执行此操作时防止主线程阻塞,或在等待时执行其他操作,但这不会加快写入速度。写入文件的限制因素通常是文件系统/硬件。除非同时写入多个文件系统,否则异步将无法提供更好的最大性能。请注意,
async
的主要好处是具有许多上下文开关的高并发应用程序。这是1k,而不是10k和更多任务的领域。对于仅2个任务,async
与线程相比没有任何好处,例如,线程也会暂停I/O以让其他线程运行。这是否回答了您的问题?另见