从python中的多个线程读取单个文件

时间:2012-02-07 12:02:32

标签: python multithreading file-io

我正在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类获取锁定,查找,读取和释放锁定;

  • 创建一个等待读取请求并以正确顺序执行它们的线程。

那么,我错过了一个明显的解决方案吗?这些方法之间是否存在显着的性能差异?

由于

3 个答案:

答案 0 :(得分:2)

如果您还没有这样做,可能需要使用Leader/Follower模式。
Leader线程将知道哪些段已被处理,哪些段未被处理,并将自己分配下一个未处理的段,然后成为关注者,将领导留给池中的下一个可用线程。

答案 1 :(得分:2)

你可以使用mmap。见mmap() vs. reading blocks

正如Tim Cooper所说,当你有随机访问时,mmap是一个好主意(多线程会使你看起来像这样),并且他们可以共享相同的物理页面。

答案 2 :(得分:1)

CPython有GIL,因此多线程不会提高CPU绑定任务的性能。

如果问题不是IO绑定(磁盘提供/存储数据的速度比CPU解压缩速度快),您可以使用multiprocessing module:每个进程打开文件并解压缩给定的字节范围。