1

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

第一个过程使用和。CreateFileMapping(INVALID_HANDLE_VALUE, ..., PAGE_READWRITE, ...)MapViewOfFile( ... FILE_MAP_WRITE)

第二个过程使用和。OpenFileMapping(FILE_MAP_WRITE, ...)MapViewOfFile( ... FILE_MAP_WRITE)

文档状态:

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

除了一个重要的例外,从由同一文件支持的任何文件映射对象派生的文件视图在特定时间是连贯的或相同的。对于进程内的视图和由不同进程映射的视图,一致性得到保证。

异常与远程文件有关。(...)

由于我只是按原样使用共享内存(由分页文件支持),我会假设进程之间需要一些同步才能看到另一个进程写入的内存的一致视图。但是我不确定究竟需要什么同步。

我目前的模式(简化)是这样的:

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

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

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

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

4

4 回答 4

1

从那以后,我开始相信,出于内存访问同步的目的,并发访问的内存是在进程之间共享还是仅在线程之间共享一个进程并不重要。

也就是说,对于 Windows 上的共享内存(进程之间共享的内存),与进程中的“正常”内存相同的限制和准则适用于仅在进程线程之间共享的进程。

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

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

于 2013-07-30T09:48:47.857 回答
0

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

于 2013-05-10T13:06:01.460 回答
0

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

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

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

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

于 2021-01-24T16:39:45.603 回答
-1

使用 Semaphore 应该比 Event 更好。

于 2013-05-10T11:49:26.290 回答