Python 进程池写入的输出文件在任意位置被切断?

Python 进程池写入的输出文件在任意位置被切断?,python,file,multiprocessing,Python,File,Multiprocessing,我正在使用一个multiprocessing.pool处理一个巨大的文件,其中的进程都在写入一个输出文件。我将输入文件划分为多个分区(基本上是两个行索引元组,稍后传递给linecache.getline())并使用pool.map(func,列出分区)。在func内部,当前进程在其给定的分区上工作(保证不会与任何其他分区重叠),然后在将结果写入单个输出文件之前,它获取一个锁,然后在写入完成后释放它。锁是使用初始值设定项创建的,因此它是继承的(取自),以便跨进程共享。以下是相关代码: l = mu

我正在使用一个
multiprocessing.pool
处理一个巨大的文件,其中的进程都在写入一个输出文件。我将输入文件划分为多个分区(基本上是两个行索引元组,稍后传递给
linecache.getline()
)并使用
pool.map(func,列出分区)
。在
func
内部,当前进程在其给定的分区上工作(保证不会与任何其他分区重叠),然后在将结果写入单个输出文件之前,它获取一个锁,然后在写入完成后释放它。锁是使用初始值设定项创建的,因此它是继承的(取自),以便跨进程共享。以下是相关代码:

l = multiprocessing.Lock() # lock
o = open("filename", 'w') # output
pool = multiprocessing.Pool(num_cores, initializer=init, initargs=(l, o,))
其中,
init
定义如下:

def init(l, o):
    global lock, output
    lock = l
    output = o
我的问题是输出文件在随机位置缺少一些文本。起初,我发现输出文件在最后被切断,但是我确认当文件的末尾添加了许多空行,并且发现文件中间的另一个文本块也丢失了部分时,它并不是排在文件末尾的。以下是预期文本块的示例:

Pairs: [(81266, 146942, 5)]
Number of pairs: 1
idx1 range: [81266, 81266]
idx2 range: [146942, 146942]
Most similar pair: (81266, 146942, 5)
Total similarity (mass): 5
这是一个被切断的街区:

Pairs: [(81267, 200604, 5)]
Number of pairs: 1
idx1 range: [81267, 81267]
idx2 range: [200604, 200604]
Most similar pair: (81267, 200604, 5)
Total similarity (ma
还有一个更严重的情况:

Pairs: [(359543, 366898, 5), (359544, 366898, 5), (359544, 366899, 6)]
Number of pairs: 3
值得一提的是,我正在做
pool.close()
然后
pool.join()
,尽管当我删除它们时问题仍然存在


你能想到会导致这种情况的原因吗?当我在没有并行性的情况下正常运行代码时,问题不会出现。我比较了由并行版本生成的文件和非并行版本生成的文件中的有效、完整输出文本块的数量(如上面给出的示例),给定相同的输入文件,发现并行版本有137073个有效块,而非并行版本有137114个有效块,因此我丢失了41个有效块(即,切断了41个不同的区块),与块的总数相比,这是一个非常小的数字,因此这确实让我感到困惑。非常感谢您的任何想法或建议!

您正在刷新输出对象吗?不,我不确定这是什么。我有一个所有进程都要写入的输出文件对象。刷新输出对象意味着什么?然后显示您的代码我们再谈。我不知道我回答你的问题时你为什么不继续,但事实证明就是这样!我添加了output.flush()然后是os.fsync(output.fileno()),问题消失了。如果您想将此作为答案,请回答。非常感谢!您不需要此级别的fsync,但您确实需要
flush
。您正在刷新输出对象吗?不,我不确定这是什么。我有一个所有进程都要写入的输出文件对象。刷新输出对象意味着什么我的意思是?展示你的代码,然后我们再谈。我不确定我回答你的问题时你为什么不继续,但结果就是这样!我添加了output.flush()然后是os.fsync(output.fileno()),问题就消失了。如果您想将此作为答案,请回答。非常感谢!您不需要此级别的fsync,但需要
刷新