无法并行读取相同的文件

Posted

技术标签:

【中文标题】无法并行读取相同的文件【英文标题】:Unable to read same file in parallel 【发布时间】:2012-08-07 22:50:57 【问题描述】:

我正在尝试同时在两个不同的应用程序中读取日志文件。但 CreateFile (http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858%28v=vs.85%29.aspx) 使用共享模式 #FILE_SHARE_READ 在第二次调用时总是失败,错误代码为 32:ERROR_SHARING_VIOLATION: - 进程无法访问该文件,因为它正被另一个进程。

当日志文件以 FILE_SHARE_WRITE 或 FILE_SHARE_READ 模式写入时 | FILE_SHARE_WRITE 只有当 FILE_SHARE_READ 用于 writer-application 时,两个应用程序中的任何一个都无法读取文件,然后它仅在 reader-applications 使用 FILE_SHARE_WRITE 或 FILE_SHARE_READ | 时才有效。 #FILE_SHARE_WRITE,而不是在使用 #FILE_SHARE_READ 时。奇怪....有什么建议吗?

非常感谢。

修改:

Writer-Application: CreateFile(file,GENERIC_WRITE,FILE_SHARE_READ,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0)
Reader-Applications: CreateFile(file,GENERIC_READ,FILE_SHARE_READ | FILE_SHARE_WRITE,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0)

修正 2:

当使用来自第一修正案的调用时,第一个阅读器应用程序可以成功获取文件句柄,但第二个阅读器应用程序将失败并出现 ERROR_SHARING_VIOLATION。

修正 3:有人指出我的解决方案!

问题是我使用逻辑或而不是按位或作为共享模式: FILE_SHARE_READ 或 FILE_SHARE_WRITE = 1 或 2 = 1,但应该是 FILE_SHARE_READ | FILE_SHARE_WRITE = 1 | 2 = 3。因此无法作为 Writer-Application 所需的 FILE_SHARE_WRITE 工作。

【问题讨论】:

您正在使用 OPEN_EXISTING 创建它,对吗?我问是因为大多数其他选项似乎有时会尝试写入文件。 你没有说你打开的是什么访问模式。共享模式必须与访问模式兼容。例如如果你说FILE_SHARE_READ,但有人打开了GENERIC_WRITE 的文件,那么打开将失败,因为你没有指定FILE_SHARE_WRITE 您为 dwDesiredAccess 参数指定了什么? 谢谢,我添加了调用参数。 也许您想要named pipe?听起来比你想做的更合适。 【参考方案1】:

这并不奇怪,但它确实会永远让程序员感到逻辑颠倒。当一个程序创建一个日志文件时,它只需要指定 FILE_SHARE_READ 来允许另一个进程读取该文件。然而,它在这样做时获得了另一种能力,它要求 GENERIC_WRITE 以便它可以写入文件。操作系统没有反对意见,它将永远保留该功能,直到关闭文件。

然后出错的是另一个进程试图打开文件但拒绝写入文件的权利。换句话说,只指定 FILE_SHARE_READ 和 not FILE_SHARE_WRITE。那是行不通的,第一个进程已经获得了写入权,您不能猛拉地板垫并说它不应该写入文件。那将是令人讨厌的拒绝服务攻击。所以操作系统说不,并且 CreateFile() 调用失败。

其他进程必须指定 FILE_SHARE_WRITE。

【讨论】:

我可能不够清楚。您的答案是正确的,从我的修改中可以看出:Writer must use FILE_SHARE_READ, Reader must use FILE_SHARE_READ | FILE_SHARE_WRITE。 但是当两个 Reader 启动并通过 CreateFile 和 FILE_SHARE_READ | 打开句柄时它不起作用FILE_SHARE_WRITE。然后后一个 Reader 将失败并显示 ERROR_SHARING_VIOLATION: The process cannot access the file because it is being used by another process.【参考方案2】:

您不能为两个不同的操作访问同一个文件,例如WRITE_TOREAD_FROM。相反,您可以为两个不同的操作克隆它。

【讨论】:

实际上您可以同时访问同一个文件进行不同的操作。这不是问题。【参考方案3】:

您不能同时进行多个操作,即读/写操作。如果文件不是太大,您可能必须在内存中复制它。

【讨论】:

确实可以同时进行多项操作。这不是问题。【参考方案4】:

是的,我在使用内存映射文件时遇到了同样的问题 - 我想创建一个 mmap 文件以供多个进程读取/写入...在 Linux/MacOS 上非常有用。

您似乎只能在 Unix 操作系统中执行此操作,我根本无法在 Windows 中重新创建此行为。

【讨论】:

问题不在于 Unix。

以上是关于无法并行读取相同的文件的主要内容,如果未能解决你的问题,请参考以下文章

读取文件时无法使用 OpenMP 获得加速

无法两次读取相同的 InputStream [重复]

如何在 DataBricks 中并行读取文件?

MPI - 平行点积计算

从 Python 并行批量读取文件

比较从文本文件中读取的并行数组