繁体   English   中英

进程之间并发文件写入

[英]Concurrent File write between processes

我需要将来自不同进程的日志数据写入单个文件。

我正在使用需要通用语言运行时支持的Windows Mutex。

Mutex^ m = gcnew Mutex( false,"MyMutex" );
m->WaitOne();
//... File Open and Write ..
m->ReleaseMutex()

我真的需要从C ++更改为C ++ / CLI进行同步吗?

如果不使用原子也可以。 但是我需要知道与本地互斥锁相比,使用此互斥锁是否会降低性能。

仅仅为了获得Mutex类而向您的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设置为dwDesiredAccess打开文件FILE_APPEND_DATA | SYNCHRONIZE FILE_APPEND_DATA | SYNCHRONIZE 以及其他所有内容 (不包含FILE_WRITE_DATA ),则操作系统将确保确保最后写入文件的所有数据以及写入数据的两个应用程序不会相互覆盖。 此行为记录在MSDN上

如果仅设置了FILE_APPEND_DATA和SYNCHRONIZE标志,则调用者只能将其写入文件的末尾,并且有关写入文件的所有偏移信息都将被忽略。 但是,此类型的写操作将根据需要自动扩展文件。

选项3:LockFile

您可以采取的另一种方法是使用LockFile方法。 使用LockFile (或LockFileEx ),可以使两个应用程序都打开文件,并使每个应用程序锁定要写入的文件部分。 与互斥锁相比,这提供了更大的粒度,从而允许同时发生不重叠的写入。 (使用LockFile整个文件会给你同样的基本效果互斥体,与额外的好处,它会防止其他应用程序写入文件,而你这样做。)还有如何使用一个很好的例子LockFileRaymond Chen的博客

实际上,您根本不需要使用单独的互斥体,您可以只使用文件本身。 通过CreateFile API调用打开文件时(请参阅https://msdn.microsoft.com/zh-cn/library/windows/desktop/aa363858%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396 ),该调用会使用名为dwShareMode的参数,该参数指定其他进程允许进行哪些并发访问。 值为0将阻止其他进程完全打开文件。

几乎所有用于在后台打开文件映射到CreateFile的API,因此当您打开已写入的文件时,clr可能为您做了正确的事情。

在C运行时中,还有_fsopen,它使您可以打开带有共享标志的文件。

我建议您测试从C#打开文件时的默认共享模式。 如果默认情况下不能阻止同时打开以进行写入,请使用C中的_fsopen(或者可能有适当的C#函数)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM