Python中写入大文件时静默失败

-1 投票
1 回答
1047 浏览
提问于 2025-04-18 10:45

我有一个程序,它使用 cPickle 来保存很大的文件(几GB)。对于小文件来说,它运行得很好(最大成功处理的文件是5.6 GB),但在处理更大的文件时却没有任何反应(!)。

不确定这是否相关,但我在多个节点上同时使用 multiprocessing 来生成和写入这些文件。我怀疑这个问题不仅仅是(c)Pickle的问题,因为我在使用 h4py 写入大文件到 HDF5 时也遇到过类似的问题。

有没有人知道可能发生了什么?

一些额外的信息: 我在使用EXT4文件系统的Linux上运行。我的内存应该足够(60 GB + 120 GB的交换空间……没有内存错误),而且每个进程都在处理一个单独的文件。没有进程被杀掉……我有一个循环,每次迭代计算一个大文件并保存。如果文件太大,它就不会被保存,进程会继续进行下一次循环,而没有任何错误信息或其他表明出错的迹象(除了缺少的文件)。

这里有一个最小的示例,可以重现这个问题:

import numpy as np
import cPickle
import multiprocessing as mp

def test():
    test = np.random.random(1000000000)
    # test = np.random.random(10000) # this works
    cPickle.dump(test, open('/home/ctw/tmp/test.pickle','w'), -1)

po = mp.Pool(1)
po.apply_async(test)
po.close()

结果是创建了一个空文件。当我在没有多进程环境下运行这个时,通常的结果是创建一个小的(127B)文件,并出现以下错误信息(在使用多进程时我从未看到过错误):

In [32]: cPickle.dump(test, open('/home/ctw/tmp/test.pickle','w'), -1)
---------------------------------------------------------------------------
SystemError                               Traceback (most recent call last)
<ipython-input-32-62283b59a617> in <module>()
----> 1 cPickle.dump(test, open('/home/ctw/tmp/test.pickle','w'), -1)

SystemError: error return without exception set

另一个更新:如果我把协议设置为0而不是-1,文件就能成功写入。

1 个回答

0

显然,在Python 3.3之前,cpickle文件的大小有个固有的限制,最大只能到2的31次方减去1。这对于使用字节协议来说是个问题。更让人感到烦恼和奇怪的是,在进行多进程处理时并不会出现任何错误提示。

撰写回答