进程之间的并发文件写入
Concurrent File write between processes
我需要将来自不同进程的日志数据写入单个文件中。
我正在使用Windows Mutex,它需要公共语言运行时支持。
Mutex^ m = gcnew Mutex( false,"MyMutex" );
m->WaitOne();
//... File Open and Write ..
m->ReleaseMutex()
我真的需要从 C++ 更改为 C++/CLI 进行同步吗?
如果不使用原子也没关系。但是我需要知道与本地互斥锁相比,使用此互斥体是否会降低性能。
仅仅为了获得互斥类而向C++应用程序添加 CLR 支持是矫枉过正的。有几个选项可用于在两个应用程序之间同步文件访问。
选项 1:互斥
如果需要从多个进程写入文件,使用互斥锁是一种好方法。使用 Win32 API 中的互斥函数。(无论如何,.Net Mutex类只是这些函数的包装器。
HANDLE mutex = CreateMutex(NULL, false, "MyMutex");
DWORD waitResult = WaitForSingleObject(mutex, INFINITE);
if (waitResult == WAIT_OBJECT_0)
{
// TODO: Write the file
WriteFile(...);
ReleaseMutex(mutex);
}
正如另一个答案所指出的,您需要通过共享打开文件,以便您的两个应用程序都可以同时打开它。但是,这本身可能还不够:如果两个应用程序都尝试写入文件的同一区域,则仍需要确保一次只有一个应用程序写入。想象一下,如果两个应用程序都查看文件的大小,那么两个应用程序都尝试同时写入该字节偏移量:即使两者都试图附加到文件的末尾,它们最终也会互相破坏。
选项 2:仅作为追加打开
如果您纯粹写入文件末尾,并且从未尝试读取任何内容或写入文件末尾以外的任何地方,那么您可以使用一种特殊模式,让您不使用互斥锁。如果您在打开文件时dwDesiredAccess
设置为 FILE_APPEND_DATA | SYNCHRONIZE
而没有其他任何内容(不包括 FILE_WRITE_DATA
),则操作系统将负责确保最后写入文件的所有数据,以及写入数据的两个应用程序不会相互覆盖。MSDN 上记录了此行为:
如果仅设置了 FILE_APPEND_DATA 和 SYNC 标志,则调用方只能写入文件末尾,并且将忽略有关写入文件的任何偏移信息。但是,该文件将根据此类写入操作的需要自动扩展。
选项 3:锁定文件
您可以采取的另一条途径是使用 LockFile
方法。使用 LockFile
(或 LockFileEx
),可以让两个应用程序打开文件,并让每个应用程序锁定要写入的文件部分。这为您提供了比互斥锁更多的粒度,允许同时进行非重叠写入。(对整个文件使用 LockFile
将提供与互斥锁相同的基本效果,但额外的好处是它将防止其他应用程序在您这样做时写入文件。在Raymond Chen的博客上有一个关于如何使用LockFile
的很好的例子。
实际上你根本不需要使用单独的互斥锁,你可以使用文件本身。当使用 CreateFile API 调用打开文件时(请参阅 https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396),该调用采用一个名为 dwShareMode 的参数,该参数指定其他进程允许的并发访问。值为 0 将阻止其他进程完全打开文件。
几乎所有用于打开文件的 API 都映射到 CreateFile,因此当您打开文件进行写入时,clr 可能会为您做正确的事情。
在 C 运行时中,还有_fsopen允许您打开带有共享标志的文件。
我建议您在从 C# 打开文件时测试默认共享模式是什么。如果默认情况下它不阻止同时打开进行写入,请使用 C 中的_fsopen(或者可能有适当的 C# 函数)。
- .cpp和.h文件中的模板专用化声明
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 文本文件中的单词链表
- CMake-按正确顺序将项目与C运行时对象文件链接
- 使用新行和不使用新行读取文件
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 挂起和取消挂起一个文件DLL
- 如何确定我已使用非编码文件到达 EOF?
- 命名空间中具有.h和.cpp文件的类
- 如何使用ndk-build.cmd构建Android.so文件
- 从包含m行的文件中提取n行,必要时(惰性地)重复该文件
- 读取文件并输入到矢量中
- 在C++中查找文件
- 如何使用 c++ 实现并发文件/文本编辑?
- 使用来自多个进程的 pantheios 并发写入日志文件
- C/C++中的并发日志文件访问
- 从文件并发处理
- 进程之间的并发文件写入
- 对Linux和Windows的多个进程的并发状态文件操作超出了我们的控制
- 使用Boost 1.55线程和文件系统并发内存损坏(Visual Studio 2013)