Re: Named shared memory without synchronization
"Dan Schwartz" <DanSchwartz@discussions.microsoft.com> wrote in message
news:FBF2C5A7-374E-4DEC-85CA-24D3D291FA83@microsoft.com
"Igor Tandetnik" wrote:
Any reasoning about the behavior of a program in the presence of
multiple threads and such is necessarily specific to a particular
implementation, not the C language in general.
Nevertheless, assuming an x64/x86 architecture (portability being a
secondary issue for me, at least for the time being) implies atomic
operations on the int level, does it not?
Yes, on both x86 and x64 operations on int are atomic, I believe. Note
however that, while x86 has strongly coherent cache, x64 (at least IA64,
I'm not sure about AMD64) has weakly coherent cache model and memory
barrier considerations apply.
What I'm trying to achieve is a sort of watchdog behavior, where one
process (the server) will
terminate another (the client) if it does not send an "I'm alive"
message within a predefined
timeout. My suggested solution works as follows:
1. Server names shared memory after the client's executable name.
2. Server defines a pointer (we'll call it x) to an integer in the
shared memory block.
3. Server runs client (createprocess etc...).
4. Client defines a pointer (x) to an integer in the shared memory
block named after its own name
5. Client does his work. Assuming the duration of the client's "main
loop" is at most t seconds,
client resets x (e.g *x=t) every t seconds.
6. Server wakes up every second and does:
if (!((*x)--)) {
terminateprocess(client);
createprocess(client);
}
I see a very obvious problem. (*x)-- operation is not atomic - it
involves reading a word from memory, decrementing, and writing new value
back. Consider this scenario: the server reads *x which happens to be 1.
Right after that the client writes, say, 10 into *x and goes back to
work, safe in the knowledge that it has performed its notification duty.
But the server saw 1, not 10. So it decrements and writes 0 back into
*x, overwriting the client's notification. A second later the server
would consider the client hung and kill it.
I strongly recommend using InterlockedDecrement on the server side, and
InterlockedExchange on the client. For an operation that only executes
once a second, what performance considerations could you possibly have?
I submit you have a bad case of premature optimization.
To the best of my understanding, the only two concerns would be:
1. That the integer pointed at by x isn't somehow corrupted by a
combined read/write.
I'm not sure what you mean by "combined read/write". There ain't no such
thing.
--
With best wishes,
Igor Tandetnik
With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925