具有进程间(un)同步多线程访问的CreateFileMapping和MapViewOfFile?

时间:2013-05-10 09:56:06

标签: winapi visual-c++ shared-memory memory-barriers file-mapping

我使用共享内存区域将som数据发送到第二个进程。

第一个流程使用CreateFileMapping (INVALID_HANDLE_VALUE, ..., PAGE_READWRITE, ...)MapViewOfFile ( ... FILE_MAP_WRITE)

第二个流程使用OpenFileMapping (FILE_MAP_WRITE, ...)MapViewOfFile ( ... FILE_MAP_WRITE)

docs州:

  

文件映射对象的多个视图   如果它们在指定时间包含相同的数据,则连贯。   如果文件视图是从任何文件映射对象派生的,则会发生这种情况   由同一个文件支持。 (...)

     

有一个重要的例外,文件视图派生自任何文件映射   由同一文件支持的对象在a处是连贯的或相同的   特定的时间。对于过程中的观点,保证一致性   对于由不同进程映射的视图。

     

该例外与远程文件有关。 (...)

由于我只是按原样使用共享内存(由页面文件支持),我假设在进程之间需要进行一些同步,以查看另一个进程编写的内存的连贯视图。但我不确定究竟需要什么同步。

我现有的模式(简化)是这样的:

Process1                    |  Process2
...                         |  ...
/* write to shared mem, */  |  ::WaitForSingleObject(hDataReady); // real code has error handling
/* then: */
::SetEvent(hDataReady);     |  /* read from shared mem after wait returns */
...                         |  ...

这是否足够同步,即使对于共享内存?

两个流程之间通常需要什么同步?

请注意,在一个进程内部,对SetEvent的调用肯定会构成full memory barrier,但我不完全清楚这是否适用于跨进程的共享内存。

4 个答案:

答案 0 :(得分:0)

使用信号量应该比事件好。

答案 1 :(得分:0)

如果这两个代码片段都在循环中,那么除了事件之外,您还需要一个互斥锁,以便Process2在读取时不会再次开始写入。更具体地说,必须在读取或写入之前获取互斥锁,并在读取或写入之后释放互斥锁。在Process2中调用WFSO之前,请确保已释放互斥锁。

答案 2 :(得分:0)

我已经相信为了内存访问同步的目的,如果并发访问的内存在进程之间共享或只是一个进程,那么它真的不重要线程之间。

也就是说,对于Windows上的共享内存(进程之间共享的内存),相同的限制和指导适用于在进程的线程之间共享的进程中的“普通”内存。

我认为这是因为进程和线程在Windows上有些正交。进程是线程的“容器”,为了使进程能够执行任何操作,它至少需要一个线程。因此,对于映射到多个进程的地址空间的内存,在这些不同进程中运行的线程的同步要求实际上应与在同一进程中运行的线程相同。

那么,我的问题的答案这是否足够同步,即使对于共享内存?是共享内存需要与“普通”内存相同的同步。但是,当然,并非所有同步技术都适用于流程边界,因此您可以使用的内容受到限制。 (示例的关键部分不能跨进程使用。)

答案 3 :(得分:0)

我的理解是,虽然 Windows 可以保证视图的一致性,但它并不能保证在客户端读取之前完全完成写入。

例如,如果您正在写“Hello world!”到视图中,客户端读取时只能部分写入,例如“Hello w”。

因此,视图将是字节连贯的,但不是消息连贯的。

就我个人而言,我使用互斥锁来保证线程安全访问。