我正在python中编写一个多线程解压缩程序。每个线程都需要访问输入文件的不同块。
注1:无法加载整个文件,因为它的范围从15 Gb到200 Gb;我不是使用多线程来加速数据读取,而是使用数据解压缩,我只是想确保数据读取不会减慢解压缩。
注2:GIL不是问题,因为主要的解压缩器功能是C扩展,它调用Py_ALLOW_THREADS,因此在解压缩时释放GIL。第二阶段减压使用numpy,也是无GIL的。
1)我认为仅仅共享Decompressor对象(基本上包装文件对象)是行不通的,因为如果线程A调用以下内容:
decompressor.seek(x)
decompressor.read(1024)
并且线程B执行相同的操作,线程A可能最终从线程B偏移量读取。这是对的吗?
2)现在我只是让每个线程创建自己的Decompressor实例,它似乎工作,但我不确定这是最好的方法。 我考虑过这些可能性:
添加类似
的内容seekandread(from_where, length)
到Decompressor类获取锁定,查找,读取和释放锁定;
创建一个等待读取请求并以正确顺序执行它们的线程。
那么,我错过了一个明显的解决方案吗?这些方法之间是否存在显着的性能差异?
由于
答案 0 :(得分:2)
如果您还没有这样做,可能需要使用Leader/Follower模式。
Leader线程将知道哪些段已被处理,哪些段未被处理,并将自己分配下一个未处理的段,然后成为关注者,将领导留给池中的下一个可用线程。
答案 1 :(得分:2)
你可以使用mmap。见mmap() vs. reading blocks
正如Tim Cooper所说,当你有随机访问时,mmap是一个好主意(多线程会使你看起来像这样),并且他们可以共享相同的物理页面。
答案 2 :(得分:1)
CPython有GIL,因此多线程不会提高CPU绑定任务的性能。
如果问题不是IO绑定(磁盘提供/存储数据的速度比CPU解压缩速度快),您可以使用multiprocessing module:每个进程打开文件并解压缩给定的字节范围。