|
Boost : |
From: Alexander Terekhov (terekhov_at_[hidden])
Date: 2002-05-23 13:32:44
"William E. Kempf" wrote:
[...]
> That said, semaphores aren't strictly "missing forever". I plan to address
> this at some point with more research into the pros/cons.
Save your time, Bill. Really.
< Forward Inline >
-------- Original Message --------
Message-ID: <3CED3306.DF6DB829_at_[hidden]>
Date: Thu, 23 May 2002 20:20:54 +0200
From: Alexander Terekhov <terekhov_at_[hidden]>
Reply-To: terekhov_at_[hidden]
Newsgroups: comp.programming.threads
Subject: Re: many semaphores
References: <b9c563f9.0205071053.37baf3c2_at_[hidden]> <3CD8FAB0.E6272694_at_[hidden]> <b9c563f9.0205090507.735ccbd2_at_[hidden]> <3CDBD51B.3B7839F8_at_[hidden]> <3CEB99C5.88A9B69B_at_[hidden]> <3CEBC872.FF262C8C_at_[hidden]> <3CEBDA71.CC4AA9AA_at_[hidden]>
Mark Johnson wrote:
[...]
> > That's fine. Why not call them "simply" LOCKS? Do you need/use
> > it for LOCKING (to protect access to your shared data) or for
> > WAITING/SIGNALING (awaiting/notifying the occurrence of some
> > condition/state reflected in your shared "items"/data)?
> >
> I guess we (and others) are dancing around terminology here. To me,
> locks and semaphores have the same semantic effects. To quote from
> Dijkstra's paper (The Structure of the "THE" Multiprogramming System,
> 1968)...
[snip P/V stuff]
Mark, *I am...* yeah: DANCING, heck, all along, around THIS:
"Semaphore Lock Operation
An operation that is applied to a semaphore. If, prior to the
operation, the value of the semaphore is zero, the semaphore
lock operation shall cause the calling thread to be blocked
and added to the set of threads awaiting the semaphore;
otherwise, the value shall be decremented.
Semaphore Unlock Operation
An operation that is applied to a semaphore. If, prior to the
operation, there are any threads in the set of threads awaiting
the semaphore, then some thread from that set shall be removed
from the set and becomes unblocked; otherwise, the semaphore
value shall be incremented."
around THIS ("Realtime"[1] stuff; semget()-semaphores associated
with the X/Open System Interface Extension (XSI) aside, "for a
moment"):
http://www.opengroup.org/onlinepubs/007904975/functions/sem_wait.html
http://www.opengroup.org/onlinepubs/007904975/functions/sem_post.html
and, around THIS:
http://www.opengroup.org/onlinepubs/007904975/xrat/xsh_chap02.html#tag_03_02_09
"....
A semaphore is defined as an object that has an integral value
and a set of blocked processes associated with it. If the value
is positive or zero, then the set of blocked processes is empty;
otherwise, the size of the set is equal to the absolute value
of the semaphore value. The value of the semaphore can be
incremented or decremented by any process with access to the
semaphore and must be done as an indivisible operation. When
a semaphore value is less than or equal to zero, any process
that attempts to lock it again will block or be informed that
it is not possible to perform the operation.
A semaphore may be used to guard access to any resource
accessible by more than one schedulable task in the system.
It is a global entity and not associated with any particular
process. As such, a method of obtaining access to the semaphore
has to be provided by the operating system. A process that wants
access to a critical resource (section) has to wait on the
semaphore that guards that resource. When the semaphore is
locked on behalf of a process, it knows that it can utilize
the resource without interference by any other cooperating
process in the system. When the process finishes its operation
on the resource, leaving it in a well-defined state, it posts
the semaphore, indicating that some other process may now
obtain the resource associated with that semaphore.
In this section, mutexes and condition variables are specified
as the synchronization mechanisms between threads.
These primitives are typically used for synchronizing threads
that share memory in a single process. However, this section
provides an option allowing the use of these synchronization
interfaces and objects between processes that share memory,
regardless of the method for sharing memory.
Much experience with semaphores shows that there are two
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
distinct uses of synchronization: locking, which is typically
of short duration; and waiting, which is typically of long or
unbounded duration. These distinct usages map directly onto
mutexes and condition variables, respectively.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Semaphores are provided in IEEE Std 1003.1-2001 primarily to
provide a means of synchronization for processes; these processes
may or may not share memory. Mutexes and condition variables are
specified as synchronization mechanisms between threads; these
threads always share (some) memory. Both are synchronization
paradigms that have been in widespread use for a number of years.
Each set of primitives is particularly well matched to certain
problems.
With respect to binary semaphores, experience has shown that
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
condition variables and mutexes are easier to use for many
synchronization problems than binary semaphores. The primary
reason for this is the explicit appearance of a Boolean
predicate that specifies when the condition wait is satisfied.
This Boolean predicate terminates a loop, including the call
to pthread_cond_wait(). As a result, extra wakeups are benign
since the predicate governs whether the thread will actually
proceed past the condition wait. With stateful primitives,
such as binary semaphores, the wakeup in itself typically
means that the wait is satisfied. The burden of ensuring
correctness for such waits is thus placed on all signalers
of the semaphore rather than on an explicitly coded Boolean
predicate located at the condition wait. Experience has
shown that the latter creates a major improvement in safety
and ease-of-use.
Counting semaphores are well matched to dealing with
producer/consumer problems, including those that might exist
between threads of different processes, or between a signal
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
handler and a thread. In the former case, there may be little
or no memory shared by the processes; in the latter case,
one is not communicating between co-equal threads, but
between a thread and an interrupt-like entity. It is for
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
these 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. The efficiency of their implementation is comparable
to or better than that of other synchronization primitives
that are sometimes harder to use (for example, binary semaphores).
Furthermore, there is at least one known implementation of Ada
tasking that uses these primitives. Mutexes and condition
^^^^^^^^^^^^^^^^^^^^^
variables together constitute an appropriate, sufficient,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
and complete set of inter-thread synchronization primitives.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
[...POSIX/clustering/cluster wide stuff...]
Uhmm.
Have you "evaluated" technologies/"ideas" related to IBM Parallel
Sysplex clustering... COUPLING FACILITY [2] (with its Lock, Cache,
and Queue/List "behavioral models" -- "structures"), I mean? ;-)
regards,
alexander.
[1] http://www.opengroup.org/onlinepubs/007904975/functions/xsh_chap02_08.html#tag_02_08
[2] http://researchweb.watson.ibm.com/journal/sj/362/nick.html
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk