thanx a lot!
% The MSDN document says Event object can be used across processes. However, I
% am wondering how this is doable?
You can use named events, or you can use DuplicateHandle to create a handle
for the remote process, then pass the handle value via some IPC mechanism.
--
Patrick TJ McPhee
East York Canada
pt...@interlog.com
: % The MSDN document says Event object can be used across processes. However, I
: % am wondering how this is doable?
: You can use named events, or you can use DuplicateHandle to create a handle
: for the remote process, then pass the handle value via some IPC mechanism.
Do Events have the same semantics as binary semaphores, i.e., if there
is no thread/process waiting to "consume" the signal, is that signal
remembered and consumed by the next thread that tries to wait?
Tom Payne
MS-auto-reset-events ARE binary semaphores (*without*
that silly/useless MS-sema-MAX count, though).
> i.e., if there
> is no thread/process waiting to "consume" the signal, is that signal
> remembered and consumed by the next thread that tries to wait?
MS-manual-reset-events are even more brain-damaged
than MS-auto-reset-events. Pulsing/SignalObjectAndWait
is broken to the point of being unusable. Continuing
the tradition of being really usefull/easy-to-use/
clearly-defined/non-error-prone/etc. MS' NEW
BABY -- *".Net"-monitors* ALSO USE THE "PULSE"
term (Pulse and PulseAll methods). That's GREAT
(but their implementation... "shared-source" I
mean, is EVEN MORE "great" ;-)).
That's it.
regards,
alexander.
: t...@cs.ucr.edu wrote:
: [...]
:> Do Events have the same semantics as binary semaphores,
: MS-auto-reset-events ARE binary semaphores (*without*
: that silly/useless MS-sema-MAX count, though).
Thanks.
:> i.e., if there
:> is no thread/process waiting to "consume" the signal, is that signal
:> remembered and consumed by the next thread that tries to wait?
: MS-manual-reset-events are even more brain-damaged
: than MS-auto-reset-events. Pulsing/SignalObjectAndWait
: is broken to the point of being unusable.
Hmmmm. What do they do? Does SignalObjectAndWait signal one
event and wait on another?
: Continuing the tradition of being really usefull/easy-to-use/
: clearly-defined/non-error-prone/etc. MS' NEW
: BABY -- *".Net"-monitors* ALSO USE THE "PULSE"
: term (Pulse and PulseAll methods). That's GREAT
You're being sarcastic??
: (but their implementation... "shared-source" I
: mean, is EVEN MORE "great" ;-)).
Microsoft? Shared-source? Surely you jest.
Tom Payne
Uselessly burn processing cycles, at best:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/synchro_3t6b.asp
(enjoy MS-style-event-based "rwlock")
and, quite/more often, simply "produce" race conditions:
http://sources.redhat.com/ml/pthreads-win32/2001/msg00158.html
(silly/buggy MSDN articles [yet another "rwlock", btw], I mean)
> Does SignalObjectAndWait signal one event and wait on another?
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/synchro_5h2s.asp
> : Continuing the tradition of being really usefull/easy-to-use/
> : clearly-defined/non-error-prone/etc. MS' NEW
> : BABY -- *".Net"-monitors* ALSO USE THE "PULSE"
> : term (Pulse and PulseAll methods). That's GREAT
>
> You're being sarcastic??
Sort of.
> : (but their implementation... "shared-source" I
> : mean, is EVEN MORE "great" ;-)).
>
> Microsoft? Shared-source? Surely you jest.
Yep (sort-of-jest), but, "nevertheless":
http://groups.google.com/groups?selm=3CC5D589.F51B11A1%40web.de
(see "Oh, Ah, BTW, my *THREADING LINK OF THE YEAR*...")
regards,
alexander.
: t...@cs.ucr.edu wrote:
: [...]
:> : MS-manual-reset-events are even more brain-damaged
:> : than MS-auto-reset-events. Pulsing/SignalObjectAndWait
:> : is broken to the point of being unusable.
:>
:> Hmmmm. What do they do?
: Uselessly burn processing cycles, at best:
: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/synchro_3t6b.asp
: (enjoy MS-style-event-based "rwlock")
: and, quite/more often, simply "produce" race conditions:
: http://sources.redhat.com/ml/pthreads-win32/2001/msg00158.html
: (silly/buggy MSDN articles [yet another "rwlock", btw], I mean)
:> Does SignalObjectAndWait signal one event and wait on another?
: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/synchro_5h2s.asp
Hmmmmm. Your description of this feature as "brain damaged" may be
overly kind. Mutexes, semaphores, and events (i.e., binary
semaphores) remember unconsumed signals. So there is no point to an
atomic signal-and-wait function involving objects of these classes.
AFIK, separately invoking signal and wait (nonatomically) will have
the same semantics.
Tom Payne
Sorry, but MUTEXES are NOT "i.e., binary semaphores)
remember unconsumed signals". Mutexes are GOOD;
semaphores (bin. or whatever) ARE BAD... in regards
to threading with shared memory/building robust sync.
protocols-with-condvars (interrupts/signals and
isolated-IPC-stuff aside).
> So there is no point to an
> atomic signal-and-wait function involving objects of these classes.
> AFIK, separately invoking signal and wait (nonatomically) will have
> the same semantics.
Uhmm. How about: "see above"/"study condvars"? ;-)
regards,
alexander.
: Sorry, but MUTEXES are NOT "i.e., binary semaphores)
: remember unconsumed signals".
Oops -- ambiguity on my part. The phrase "(i.e., binary semaphores)"
was meant to apply to "events", not to "Mutexes, semaphores, and
events".
: Mutexes are GOOD;
: semaphores (bin. or whatever) ARE BAD... in regards
: to threading with shared memory/building robust sync.
: protocols-with-condvars (interrupts/signals and
: isolated-IPC-stuff aside).
I don't see the operational difference between a mutex and a binary
semaphore other than the names of their corresponding services (e.g.,
"lock" vs. "acquire") and the restrictions on the use of mutexes:
- no locking by the owner (recursive locking),
- no unlocking by a non-owner (gratuitous unlocking).
Specifically, if one observes those same restrictions when using of a
binary semaphore, it will behave exactly like a mutex.
:> So there is no point to an
:> atomic signal-and-wait function involving objects of these classes.
:> AFIK, separately invoking signal and wait (nonatomically) will have
:> the same semantics.
: Uhmm. How about: "see above"/"study condvars"? ;-)
Are you claiming that "an atomic signal-and-wait function" brings
significant new functionality not already available via its non-atomic
constituents? If so, I don't see how anyting "above" or the "study
[of] convars" contributes to resolving the matter. If not, what's
your point?
Tom Payne
Well, that's a "classic" mutex. While I really hate
recursive locking, it (i.e. recursive mutex) could be
easily implemented on top of a single non-recursive
one PLUS TSD (as one possible solution):
http://groups.google.com/groups?selm=c29b5e33.0201300253.5f94f544%40posting.google.com
(Note that here it DOES use bin.sema for rec.mutex, but that's
because there is just no *PROCESS_SHARED mutexes* on Linux,
which (i.e. using them instead) would be much better than
silly bin.semas, I guess ;-))
> - no unlocking by a non-owner (gratuitous unlocking).
> Specifically, if one observes those same restrictions when using of a
> binary semaphore, it will behave exactly like a mutex.
Yes, but semas are meant for both locking and signaling/waiting
(Oh, and even "counting", BTW ;-)) -- that's just too many things
at once/together! ;-) THAT makes them less efficient, harder to
use, etc. than mutexes (for locking) AND condvars (for signaling/
waiting), in my view:
http://groups.google.com/groups?selm=c29b5e33.0202011147.98b216e%40posting.google.com
http://groups.google.com/groups?selm=c29b5e33.0201310709.3ffc3476%40posting.google.com
http://groups.google.com/groups?selm=slrn9e684t.hp.kaz%40cafe.net
http://groups.google.com/groups?selm=3C5A4701.FC906236%40web.de
> :> So there is no point to an
> :> atomic signal-and-wait function involving objects of these classes.
> :> AFIK, separately invoking signal and wait (nonatomically) will have
> :> the same semantics.
>
> : Uhmm. How about: "see above"/"study condvars"? ;-)
>
> Are you claiming that "an atomic signal-and-wait function" brings
> significant new functionality not already available via its non-atomic
> constituents? If so, I don't see how anyting "above" or the "study
> [of] convars" contributes to resolving the matter. If not, what's
> your point?
My point is that "an atomic signal-and-wait function" indeed brings
significant new functionality -- *that's CONDVARS*. They have NO
state; they are really simple, and, together with mutexes are really
helpful in regards to resolving the matters of building robust and
simple and efficient and easy to understand/non-error-prone and etc.
(etc. GOOD things) synchronization protocols.
regards,
alexander.
: t...@cs.ucr.edu wrote:
[...]
: Well, that's a "classic" mutex. While I really hate
: recursive locking,
In my experience, it is a good thing to hate. Recursive locking never
solved a real problem for me, but lead me into lots of stupid designs
that were difficult to debug.
: it (i.e. recursive mutex) could be
: easily implemented on top of a single non-recursive
: one PLUS TSD (as one possible solution):
It's easy to put a recursion supporting wrapper around a non-recursive
lock/mutex. Also, a binary semaphore is a special kind of
non-recursive lock/mutex. Specifically, the behavior of a
non-recursive lock/mutex is undefined following a recusive acquisition
or a gratuitous release, but the behavior of a binary semaphore is
well defined in such instances, e.g., recursive acquisition yields a
deadlock.
: http://groups.google.com/groups?selm=c29b5e33.0201300253.5f94f544%40posting.google.com
: (Note that here it DOES use bin.sema for rec.mutex, but that's
: because there is just no *PROCESS_SHARED mutexes* on Linux,
: which (i.e. using them instead) would be much better than
: silly bin.semas, I guess ;-))
I don't see why.
:> - no unlocking by a non-owner (gratuitous unlocking).
:> Specifically, if one observes those same restrictions when using of a
:> binary semaphore, it will behave exactly like a mutex.
: Yes, but semas are meant for both locking and signaling/waiting
: (Oh, and even "counting", BTW ;-)) -- that's just too many things
: at once/together! ;-)
Right. Semaphores are the goto's of concurency. They should be "considered
harmful."
: THAT makes them less efficient,
I don't think so.
: harder to use, etc. than mutexes (for locking) AND condvars (for signaling/
: waiting), in my view:
I agree.
[...]
: My point is that "an atomic signal-and-wait function" indeed brings
: significant new functionality -- *that's CONDVARS*.
AFAIK, we don't need atomic signal-and-wait on mutexes, semaphonres, or
events to implement condvars.
: They have NO
: state; they are really simple, and, together with mutexes are really
: helpful in regards to resolving the matters of building robust and
: simple and efficient and easy to understand/non-error-prone and etc.
: (etc. GOOD things) synchronization protocols.
I agree.
Tom Payne
Nope. Another thread could "always" come-in and *unlock*
(that's the modern name of "post"-"incr"-operation, BTW)
that so-to-speak-"deadlock"-on-bin.sema. ;-) Or am I just
missing something (it's rather "late-night" now here ;-))?
> : http://groups.google.com/groups?selm=c29b5e33.0201300253.5f94f544%40posting.google.com
> : (Note that here it DOES use bin.sema for rec.mutex, but that's
> : because there is just no *PROCESS_SHARED mutexes* on Linux,
> : which (i.e. using them instead) would be much better than
> : silly bin.semas, I guess ;-))
>
> I don't see why.
They (semas) are more "expensive" than mutexes, which
could easily be "implemented" as a spinlocks, (on MP,
most-of-the-time, I mean) for example. They SHOULD be
optimized for "short" duration of being locked (which
is good). It does not really make sense (to me) to do
it w.r.t. semas. That's just one reason... (I wanna
drive to sleep ;-)) and I have no time now to {re-}
mention other "reasons", sorry.
regards,
alexander.
: t...@cs.ucr.edu wrote:
: [...]
:> It's easy to put a recursion supporting wrapper around a non-recursive
:> lock/mutex. Also, a binary semaphore is a special kind of
:> non-recursive lock/mutex. Specifically, the behavior of a
:> non-recursive lock/mutex is undefined following a recusive acquisition
:> or a gratuitous release, but the behavior of a binary semaphore is
:> well defined in such instances, e.g., recursive acquisition yields a
:> deadlock.
: Nope. Another thread could "always" come-in and *unlock*
: (that's the modern name of "post"-"incr"-operation, BTW)
: that so-to-speak-"deadlock"-on-bin.sema. ;-) Or am I just
: missing something (it's rather "late-night" now here ;-))?
You missed my point, which is that, unlike mutexes, binary semaphores
have well-defined behavior under all patterns of acquisition and
release. More over that behavior conforms to the specifcations for
mutexes provided that the preconditions for mutexes are observed. My
example, "recursive acquisition yields a deadlock" was meant only to
show an easily characterized instance of semaphores well defined
behavior in a situation where (non-recursive) mutexes have undefined
behavior. Your very correct comment shows that I was a bit careless
and should have said, "In the absence of gratuitous releases,
recursive acquisition yields a deadlock [for binary semaphores]."
:> : http://groups.google.com/groups?selm=c29b5e33.0201300253.5f94f544%40posting.google.com
:> : (Note that here it DOES use bin.sema for rec.mutex, but that's
:> : because there is just no *PROCESS_SHARED mutexes* on Linux,
:> : which (i.e. using them instead) would be much better than
:> : silly bin.semas, I guess ;-))
:>
:> I don't see why.
: They (semas) are more "expensive" than mutexes, which
: could easily be "implemented" as a spinlocks, (on MP,
: most-of-the-time, I mean) for example. They SHOULD be
: optimized for "short" duration of being locked (which
: is good). It does not really make sense (to me) to do
: it w.r.t. semas. That's just one reason...
I agree, but AFIK spinlocks conform to the semantic specifications for
binary semaphores, and I've seen books call them "binary semaphores."
99.9% of the time, however, when someone uses the term "semaphore,"
they expect the waiting to be passive.
: (I wanna drive to sleep ;-)) and I have no time now to {re-}
: mention other "reasons", sorry.
Good idea! More later? :-)
Tom Payne
Except counter-priority-inversion protocols (spinlock-"mutexes"
aside) and a few other things... please see below.
> More over that behavior conforms to the specifcations for
> mutexes provided that the preconditions for mutexes are observed. My
> example, "recursive acquisition yields a deadlock" was meant only to
> show an easily characterized instance of semaphores well defined
> behavior in a situation where (non-recursive) mutexes have undefined
> behavior. Your very correct comment shows that I was a bit careless
> and should have said, "In the absence of gratuitous releases,
> recursive acquisition yields a deadlock [for binary semaphores]."
>
> :> : http://groups.google.com/groups?selm=c29b5e33.0201300253.5f94f544%40posting.google.com
> :> : (Note that here it DOES use bin.sema for rec.mutex, but that's
> :> : because there is just no *PROCESS_SHARED mutexes* on Linux,
> :> : which (i.e. using them instead) would be much better than
> :> : silly bin.semas, I guess ;-))
> :>
> :> I don't see why.
>
> : They (semas) are more "expensive" than mutexes, which
> : could easily be "implemented" as a spinlocks, (on MP,
> : most-of-the-time, I mean) for example. They SHOULD be
> : optimized for "short" duration of being locked (which
> : is good). It does not really make sense (to me) to do
> : it w.r.t. semas. That's just one reason...
>
> I agree, but AFIK spinlocks conform to the semantic specifications for
> binary semaphores, and I've seen books call them "binary semaphores."
I'd rather call them "spinlocks" or, actually:
'pthread_spinlock_t's. ;-)
> 99.9% of the time, however, when someone uses the term "semaphore,"
> they expect the waiting to be passive.
Yep. Semas ARE (similar to condvars) meant (in the
modern world, as I see it ;-)) for SIGNALING (with
"passive" waiting), just like MUCH MORE SUPERIOR
condvars; *NOT* for locking!
> : (I wanna drive to sleep ;-)) and I have no time now to {re-}
> : mention other "reasons", sorry.
>
> Good idea! More later? :-)
Sure. Here we go:
A) Mutexes are meant for "short" locking (NOT for
long or unbound "waiting") duration, see above.
Semas are actually a mixture of TWO concepts:
-- locking (right choice: mutexes);
-- waiting (right choice: condvars).
B) Ownership/*priority inversion*...
Mutexes have OWNERS -- the implementation KNOWS
which thread (if any) currently owns it. THAT
makes it possible (optionally) to do things like
priority inheritance or ceiling MUTEX protocols/
functions.
That doesn't work with semas (they have state,
but NO ownership/thread identity w.r.t. its
"current owner"), unless I'm just missing
something here.
C) Thread cancellation and "locking"...
Since sema's lock-operation is actually a "wait"-
thing (it's even called _wait() ;-)), you just
ought to make it a cancel point -- to break-out
threads from "long/unbound" waits, etc.
That's somewhat "expensive" (I guess ;-)) and
is a rather silly thing with respect to *TRUE*
locking (mutex-locking, I mean). Please see the
POSIX Threads Rationale on this.
D) Signals/EINTR...
Mutexes do NOT (actually, are prohibited to) return
this thing. Is this good or bad? Personally, I know
the answer, for sure. ;-)
E) Signals/async-signal-safety...
Sema's unlock/post-oper is required to be
async-cancel-safe. Unless I'm missing something
THAT does NOT come for free... otherwise we would
have the "entire" pthread_ interface required made
async-signal-safe, I guess. ;-) BTW, this "feature"
(signaling fromm signal handlers) and IPC sync-w/o-
shared-mem are the only <quote>"reasons that IEEE Std
1003.1-2001 allows semaphores to be used by threads.
Mutexes and condition variables have been effectively
used with and without priority inheritance, priority
ceiling, and other attributes to synchronize threads
that share memory." -- please see the POSIX Threads
Rationale (link is can be found in this thread).
Oh! Daniel, and THAT is *specifically* for you:
"Mutexes and condition variables together constitute
an appropriate, sufficient, and complete set of
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
inter-thread synchronization primitives"
F) Building general purpose sync.protocols...
With mutexes and convars one could build whatever
sync.protocol(s) s/he wants ("fairness", whatever).
That doesn't really work with semas... unless, of
course, condvars are "emulated" via semas -- rather
inefficient thing (requires passing "gate" ownership
across thread context switches, etc.) to begin with.
And, BTW... it's NOT that simple -- which is good;
"challenging engineering puzzle/exercise", I mean. ;-).
Enough "reasons"? ;-) ;-)
regards,
alexander.
My, I've totally screwed up that bit (my poor English aside,
just got yet another phone call [fifth or so this "morning"]
from my wife ;-))!
E) Signals/async-signal-safety...
Sema's unlock/post-oper is required to be
async-signal-safe. Unless I'm missing something,
THAT does NOT come for free... otherwise we would
have the "entire" pthread_ interface made
async-signal-safe, I guess. ;-) BTW, this "feature"
(signaling from signal handlers) and IPC sync-w/o-
shared-mem are the only <quote>"reasons that IEEE Std
1003.1-2001 allows semaphores to be used by threads.
Mutexes and condition variables have been effectively
used with and without priority inheritance, priority
ceiling, and other attributes to synchronize threads
that share memory." -- please see the POSIX Threads
Rationale (link can be found in this thread).
regards,
alexander.
: A) Mutexes are meant for "short" locking (NOT for
: long or unbound "waiting") duration, see above.
Agreed, but that's not an operational difference.
: Semas are actually a mixture of TWO concepts:
: -- locking (right choice: mutexes);
: -- waiting (right choice: condvars).
Agreed, but that's not an operational difference.
: B) Ownership/*priority inversion*...
: Mutexes have OWNERS -- the implementation KNOWS
: which thread (if any) currently owns it.
Per my understanding of mutexes (which predates MS and Pthreads), they
have owners but their owners do not have to be implementation known, a
raw spinlock doesn't keep track of its owner. (Owner tracking as a
compile time option is a great diagnostic aid.)
: THAT makes it possible (optionally) to do things like
: priority inheritance or ceiling MUTEX protocols/
: functions.
Priority inheritance is an embellishment that goes well beyond the
basic notion of a mutex (e.g., simple spinlocks).
: That doesn't work with semas (they have state,
: but NO ownership/thread identity w.r.t. its
: "current owner"), unless I'm just missing
: something here.
At best, such an embellishment of semaphores would make them more
grotesque than they already are. ;-) I suspect that you are correct
that it would be impossible to define in a consistent way, but I
don't care to think about it.
: C) Thread cancellation and "locking"...
: Since sema's lock-operation is actually a "wait"-
: thing (it's even called _wait() ;-)),
Originally it was called "V". I've also see it called "acquire" and
"request".
: you just ought to make it a cancel point -- to break-out
: threads from "long/unbound" waits, etc.
Timeouts and other nonstandard resumptions are important
embellishments that can be added to semaphores. But since I don't
recommend using semaphores, I don't see why they should be
embellished.
: That's somewhat "expensive" (I guess ;-)) and
: is a rather silly thing with respect to *TRUE*
: locking (mutex-locking, I mean). Please see the
: POSIX Threads Rationale on this.
Agreed.
: D) Signals/EINTR...
: Mutexes do NOT (actually, are prohibited to) return
: this thing. Is this good or bad? Personally, I know
: the answer, for sure. ;-)
If semaphores do this, it's a nonstandard embellishment.
: E) Signals/async-signal-safety...
: Sema's unlock/post-oper is required to be
: async-cancel-safe. Unless I'm missing something
: THAT does NOT come for free... otherwise we would
: have the "entire" pthread_ interface required made
: async-signal-safe, I guess. ;-)
Another embellishment, and probably not free.
: BTW, this "feature"
: (signaling fromm signal handlers) and IPC sync-w/o-
: shared-mem are the only <quote>"reasons that IEEE Std
: 1003.1-2001 allows semaphores to be used by threads.
: Mutexes and condition variables have been effectively
: used with and without priority inheritance, priority
: ceiling, and other attributes to synchronize threads
: that share memory." -- please see the POSIX Threads
: Rationale (link is can be found in this thread).
So, semaphores are a legacy feature that has been embellished a bit to
make them function more gracefully with threads, mutexes and
conditions.
: Oh! Daniel, and THAT is *specifically* for you:
: "Mutexes and condition variables together constitute
: an appropriate, sufficient, and complete set of
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
: inter-thread synchronization primitives"
Agreed. Embellishments (e.g., priorities, nonstandard resumption, and
asynch cancellation) aside, one can implement mutexes and conditions
in terms of semaphores --- a fact that is mostly an academic
curiosity, except for those occasional situations where nothing else
is available. Fortunately, such situations are getting rarer.
: F) Building general purpose sync.protocols...
: With mutexes and convars one could build whatever
: sync.protocol(s) s/he wants ("fairness", whatever).
: That doesn't really work with semas... unless, of
: course, condvars are "emulated" via semas -- rather
: inefficient thing (requires passing "gate" ownership
: across thread context switches, etc.) to begin with.
: And, BTW... it's NOT that simple -- which is good;
: "challenging engineering puzzle/exercise", I mean. ;-).
Achieving the basic semantics of mutexes and convars is relatively
simple if one is willing to put up with the overhead of Hoare
semantics for signalling. I've not found simple solutions, however,
for even the simplest embellishments.
: Enough "reasons"? ;-) ;-)
Yes. Thanks. So back to atomic signal-and-wait. ...
Tom Payne