两个进程读取/写入同一个文件 - Win32 使用 LockFileEx() 函数

Posted

技术标签:

【中文标题】两个进程读取/写入同一个文件 - Win32 使用 LockFileEx() 函数【英文标题】:Two processes reading/writing to the same file - Win32 using LockFileEx() Function 【发布时间】:2012-07-12 08:21:40 【问题描述】:

我正在编写一个服务,它将创建一个文件并在其中写入记录,其他进程(有四个并发进程)将读取一个记录并修改它的一些值。我目前正在使用LockFileEx()UnLockFileEx() 函数进行排序。

我正在使用 createFile 函数通过我的服务创建文件,如下所示

FILEHANDLE = ::CreateFile ( TEXT("C:\\abc.BIN"),
                            GENERIC_READ | GENERIC_WRITE,
                            0,
                            NULL,
                            OPEN_ALWAYS ,
                            FILE_ATTRIBUTE_NORMAL,
                            NULL );

和其他进程获取文件的句柄,如下所示:

FILEHANDLE = ::CreateFile(TEXT("C:\\abc.BIN"),
                          GENERIC_READ |  GENERIC_WRITE,
                          0,
                          NULL,
                          OPEN_EXISTING,
                          FILE_ATTRIBUTE_NORMAL,
                          NULL);

问题是两个或多个进程无法同时获取文件的句柄。当一个进程正在写入文件时,即使我使用LockFileEx() 函数锁定文件的指定区域而不是完整文件,其他进程甚至无法获取文件句柄来读取文件。每次尝试通过设置 FILE_SHARED_READ 标志打开文件或尝试以独占方式打开文件时,我都会收到系统错误代码 32。当我设置FILE_SHARE_READ | FILE_SHARE_WRITE 时,会发生死锁。

请告诉我任何解决方案,以便我可以通过多个进程打开文件。

谢谢!!

【问题讨论】:

【参考方案1】:

您的所有进程都在请求独占访问,这就是它们无法同时获取文件句柄的原因。您必须在所有进程中同时指定FILE_SHARE_READFILE_SHARE_WRITE,因为它们都在请求对文件的读写访问。这本身不会导致死锁。所以你一定是误用了LockFileEx(),但是你没有显示那个代码。

【讨论】:

我编辑了我的代码,现在创建文件函数如下所示: FILEHANDLE = ::CreateFile ( TEXT("C:\\abc.BIN"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS ,文件属性正常,空);并且不同的并发进程正在获取文件句柄:FILEHANDLE = ::CreateFile(TEXT("C:\\abc.BIN"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);。 这里是 lockFileEx() 函数: bool boollockfile = ::LockFileEx(inFile, LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY, 0, cbLockLow, 0, &lpOverlapped);其中 cbLockLow 参数是在进程写入之前要锁定的字节数。当我同时指定 GENERIC_READ | GENERIC_WRITE 和 FILE_SHARE_READ | FILE_SHARE_WRITE,当我的第三个进程要写时发生死锁。

以上是关于两个进程读取/写入同一个文件 - Win32 使用 LockFileEx() 函数的主要内容,如果未能解决你的问题,请参考以下文章

如何使用win32 CreateProcess函数等到孩子完成写入文件

Win32 进程间通信分配

Perl - Win32 - 如何从另一个进程非阻塞读取文件句柄?

在重定向的stdout管道上禁用缓冲(Win32 API,C ++)

Windows进程间共享内存通信实例

如何在文件写入时防止其他人读取/写入文件