如何解决随后异步解开大文件
我有一个腌制列表目录,我想依次加载它,用作操作的一部分,然后丢弃。腌制后的文件大小约为0.75-2GB,我可以随时在内存中加载一个数字,尽管距离所有文件都不远。每个腌制的文件代表一天的数据。
当前,解进程占用程序运行时的很大一部分。我建议的解决方案是加载第一个文件,然后在该文件上运行操作时,异步加载列表中的下一个文件。
我想到了两种方法可以做到这一点:1)线程化和2)Asyncio。我尝试了这两种方法,但似乎都没有用。以下是我(基于尝试)的基于线程的解决方案的实现。
import os
import threading
import pickle
class DataSource:
def __init__(self,folder):
self.folder = folder
self.next_file = None
def get(self):
if self.next_file is None:
self.load_file()
data = self.next_file
io_thread = threading.Thread(target=self.load_file,daemon=True)
io_thread.start()
return data
def get_next_file(self):
for filename in sorted(os.listdir(self.folder)):
yield self.folder + filename
def load_file(self):
self.next_file = pickle.load(open(next(self.get_next_file()),"rb"))
主程序将调用 DataSource()。get()来检索每个文件。第一次加载文件时, load_file()会将文件加载到 next_file 中,并在其中存储文件。然后,线程 io_thread 应该将每个连续的文件加载到 next_file 中,以根据需要通过 get()返回。
启动的线程确实可以完成某些工作(它消耗大量的RAM,约60GB),但似乎没有更新 next_file 。
有人可以建议为什么这不起作用吗?另外,是否有更好的方法来达到此效果?
谢谢
解决方法
DataSource().get()
似乎是您的第一个问题:这意味着您将始终创建DataSource类的新实例,并且只会加载第一个文件,因为您再也不会调用同一DataSource对象实例了,您将继续下一个文件。也许您打算按照以下方式进行操作:
datasource = DataSource()
while datasource.not_done():
datasource.get()
共享完整代码非常有用,最好在repl.it或可执行代码的地方共享。
此外,如果您想获得更好的性能,那么我可能值得研究一下多处理模块,因为Python会使用全局解释器锁(GIL)阻止某些操作,从而即使一次运行多个线程,一次也只能运行一个线程。 CPU核。但这可能不是问题,因为从磁盘读取可能是瓶颈,我想Python在执行底层本机代码以从文件系统读取时会释放锁。
我也很好奇您如何使用asyncio来腌制..我猜您先从文件中读取了腌制的mem,然后在完成后解开,同时在加载过程中进行了其他处理。看来它可以很好地工作。
最后,我将添加调试打印以查看发生了什么。
更新:下一个问题似乎是您错误地使用了get_next_file生成器。每次都使用self.get_next_file()在此处创建一个新的生成器,因此您只会加载第一个文件。您只应创建一次生成器,然后在其上调用next()。也许这有助于理解,也可以在replit上查看:
def get_next_file():
for filename in ['a','b','c']:
yield filename
for n in get_next_file():
print(n)
print("---")
print(next(get_next_file()))
print(next(get_next_file()))
print(next(get_next_file()))
print("---")
gen = get_next_file()
print(gen)
print(next(gen))
print(next(gen))
print(next(gen))
输出:
a
b
c
---
a
a
a
---
<generator object get_next_file at 0x7ff4757f6cf0>
a
b
c
https://repl.it/@ToniAlatalo/PythonYieldNext#main.py
同样,调试打印将帮助您了解正在发生的事情,何时加载的文件等。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。