I use a Shared Memory area to get som data to a second process.

The first process uses CreateFileMapping(INVALID_HANDLE_VALUE, ..., PAGE_READWRITE, ...) and MapViewOfFile( ... FILE_MAP_WRITE).

The second process uses OpenFileMapping(FILE_MAP_WRITE, ...) and MapViewOfFile( ... FILE_MAP_WRITE).

The docs state:

Multiple views of a file mapping object are coherent if they contain identical data at a specified time. This occurs if the file views are derived from any file mapping object that is backed by the same file. (...)

With one important exception, file views derived from any file mapping object that is backed by the same file are coherent or identical at a specific time. Coherency is guaranteed for views within a process and for views that are mapped by different processes.

The exception is related to remote files. (...)

Since I'm just using the Shared Memory as is (backed by the paging file) I would have assumed that some synchronization is needed between processes to see a coherent view of the memory another process has written. I'm unsure however what synchronization would be needed exactly.

The current pattern I have (simplified) is like this:

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

Is this enough synchronization, even for shared memory?

What sync is needed in general between the two processes?

Note that inside of one single process, the call to SetEvent would certainly constitute a full memory barrier, but it isn't completely clear to me whether that holds for shared memory across processes.

有帮助吗?

解决方案

I have since come to believe that for memory-access synchronization purposes, it really does not matter if the concurrently accessed memory is shared between processes or just withing one process between threads.

That is, for Shared Memory (the one shared between processes) on Windows, the same restrictions and guidelines apply as with "normal" memory within a process that is just shared between the threads of the process.

The reason I believe this is that a process and a thread are somewhat orthogonal on Windows. A process is a "container" for threads, and in order for the process to be able to do anything, it needs at least one thread. So, for memory that is mapped into multiple process' address space, the synchronization requirements on the threads running within these different processes should be actually the same as for threads running within the same process.

So, the answer to my question Is this enough synchronization, even for shared memory? is that shared memory requires the same synchronization as "normal" memory. But of course, not all synchronization techniques works across process boundaries, so you are restricted in what you can use. (A Critical Section for exampled cannot be used across processes.)

其他提示

If both of those code snippets are in a loop then in addition to the event you'll need a mutex so that Process1 doesn't start writing again while Process2 is still reading. To be more specific, the mutex must be acquired before reading or writing and released after reading or writing. Make sure the mutex has been released before calling WFSO in Process2.

My understanding is that although Windows may guarantee view coherency, it does not guarantee a write is fully completed before the client reads it.

For example, if you were writing "Hello world!" to the view, it could only be partially written when the client reads it, such as "Hello w".

Therefore, the view would be byte coherent, but not message coherent.

Personally, I use a mutex to guarantee thread-safe access.

Use Semaphore should be better than Event.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top