无法并行读取相同的文件
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_TO
或READ_FROM
。相反,您可以为两个不同的操作克隆它。
【讨论】:
实际上您可以同时访问同一个文件进行不同的操作。这不是问题。【参考方案3】:您不能同时进行多个操作,即读/写操作。如果文件不是太大,您可能必须在内存中复制它。
【讨论】:
确实可以同时进行多项操作。这不是问题。【参考方案4】:是的,我在使用内存映射文件时遇到了同样的问题 - 我想创建一个 mmap 文件以供多个进程读取/写入...在 Linux/MacOS 上非常有用。
您似乎只能在 Unix 操作系统中执行此操作,我根本无法在 Windows 中重新创建此行为。
【讨论】:
问题不在于 Unix。以上是关于无法并行读取相同的文件的主要内容,如果未能解决你的问题,请参考以下文章