Boost logo

Boost :

From: Victor A. Wagner, Jr. (vawjr_at_[hidden])
Date: 2002-05-19 11:46:18

At Sunday 2002/05/19 04:34, you wrote:

> > I guess you've never seen one. There is NO hazard of electrocution
> > while attempting to put your lock on.. you're not in the hazard area.
> > And it doesn't matter who locks it "first" you both then get to go do
> > your work.
>In the real world, there isn't because people will cooperate. But
>when implementing this in code this is a problem, unless you have
>serialized access to the resource itself. This is what could happen
>if the resource is not serialized.
> T1: is power on? No? keep going.
> T2: is power on? No? keep going.
> T1: <delayed by scheduler> (almost in the dangerzone)
> T2: lock added, do work
> T2: remove lock (left danger zone)
> T3: turn on power (T1 hasn't finished adding its lock,
> and its already past the point where it would wait for the power
> to turn off.)

I don't understand how we get here. T1 doesn't go "do work" unless HIS
lock is on the circuit breaker keeping it from being closed (and the power
being turned on)

> T1: <scheduler resumes> bad things happen, T1 is working
> with the power on.
>If T1 was able to resume before T2 left the work area then T3 wouldn't
>hurt anything by turning the power on. Its a race condition. Even with
>only two thread, one going in to do work and one waiting for the power
>its possible this condition exists. If you place all the serialization
>controls within the resource, and you choose the correct kinds of
>controls, you can eliminate this problem.

I assert there is no problem.

>(I haven't seen one in the real world BTW, so I'm working from my
>understanding of the scenario you described)
> > I'm in favor of semaphores, but my review of the message history shows
> > that some felt they were "too dangerous" (a shame, IMO).
>This would be a good use for a read-write lock actually now that I think
>of it. It just struck me as I was writing part of this message, so
>I'm mentioning it here. The reason people feel a semaphore alone is too
>dangerous is because it is too dangerous.

eliding the word "too" makes your opinion agree with mine.
Filling all of memory with zeros is dangerous also
setting your priority to as high as possible then doing while(1); is dangerous
SO??? At least semaphores have utility (which outweighs their hazard, IMO).
One can easily wrap a mutex around a semaphore, the other way is somewhat
more problematic.

>You need to model a safe count
>for the number of padlocks on the resource. If it was done with just a
>semaphore, there would be no way to make sure that no one is in the
>danger zone when the power gets turned on.

but with "just a semaphore" I _can_ model it. I canNOT with a "whoever
successfully locked this mutex is the only person who can signal it" type
of animal (without an additional thread and some inter-thread synchronization).

>class Resource {
> Semaphore sema;
> void addPadlock() { sema.increment(); }
> void delPadlock() { sema.decrement(); }
> void powerOn() {
> if(sema.count() > 0)
> throw;
> // No synchronization here - count may change
> // before the power goes on.
> // turn the power on ...
> }
>You need to serialize access to the resource to implement this safely. If
>you wanted to add blocking for threads trying to get into the danger zone
>and threads coming trying to turn the power one (so people wait until its
>sage to do either thing) you'd need a pair of semaphores to do that,
>minimally - but you still need serial access to the resource for saftey,
>so using condition variables for that would be a better choice.
>If you have a way to safely do this semaphores, please share it.
> > mayhaps, yet we transfer "ownership" of other things (logically, as
> > in "who calls delete on this pointer?", and automagically as int
> > auto_ptr<>). I submit that transferring "ownership" of a resource is no
> > different.
>I might have been using the ownership term vaguely, I take an OO approach
>to these things so to me, many things are kinds of locks. Not all of them
>have owners, they hold locks (for example, who "owns" a read lock on a
>read-write lock? more than one thread can) and some locks can be held
>by several threads at the same time. So its sort of misleading to talk
>about ownership if it isn't really exclusive (for me anyway). I'll be more
>careful this time in order to be clearer.
>What is the advantage to externalizing the synchronization controls for
>some resource? In the example I showed, its very easy to see how and
>when things are locked, the code using the resource only needs to know
>how to use the resource - its the resource's responsiblity to make sure
>the access is safe. There is only 1 place in the code where you'd need
>to check to make sure the locks are correctly locked (in the resources
>code). If you model this with auto_ptr type semantics, you will succeed
>in distributing the synchronization logic throughout every piece of code
>using the resource, its more complicated (you have to following the
>assignments of locked_ptr's to see where the "ownership" currently is). Is
>there a benefit to that?
>I don't understand why a client of some piece of code should ever
>explicitly do anything to control serialization of something it uses. If
>there is a resource that requires synchronization, the resource itself
>should be responsible for that, not the client. Why burden the client?
>A client may not always know when a resource needs to be synchronized
>unless you want to expose alot of the details about that resource to
>a client (which makes a good OO design difficult).
> > I read all the words, and I don't understand what you're trying to say.
>What I'm saying is basically two things, one is that a lock has to lock
>something. In the example I showed, the lock was for the resource to
>secure access to it. If you are saying that you want to model this by
>sharing many locks owned by many workers in someway in order to synchronize
>access to one resource, then what is each lock really for? What makes that
>choice more attractive than use just a single lock? I'm not sure if this is
>what you meant in your original post or not - but it seemed this was what you
>wanted to do from your explination.
>The second thing is that if your design your code so that a lock for a
>resource is never exposed in anyway to any client of the resource,
>there is no need to burden the client with using a special pointer to that
>object that will automaticaly transfer "ownership". You can implicitly
>transfer the "ownership" of the lock by calling a function on the shared
>class Resource {
> Mutex lock;
> void doSomething() {
> Guard<Mutex> g(lock);
> // "ownership" implicity transfered to the caller
> }
>To me anyway, this is a tighter design, the lock never has to be
>exposed to anything outside the bank. You can still use this kind of
>approach to make sure a lock is held for a longer duration of time without
>the client of the resource ever needing to know anything directly about
>_how_ serialization is being provided.
>class Bank {
> Mutex lock;
> void commit(Transaction& t) {
> Guard<Mutex> g(lock);
> // "ownership" transfered to the execute() function
> t.execute();
> }
>You can transfer "ownership" of a lock very easily this way and you
>end up with something that is more flexible and has fewer dependancies
>(the transaction doesn't need to depend on the Bank, and the Bank doesn't
>need to pray the Transaction does the right thing) I've always have been
>able to do this and if I have ever found that I'm in a situation where I
>suddenly need to know about another objects lock then I take it as
>indication that my design is somewhat convoluted and has a problem. not
>the synchornization model. Just break the problem down differently.
>- Eric
>Unsubscribe & other changes:

Victor A. Wagner Jr.
PGP RSA fingerprint = 4D20 EBF6 0101 B069 3817 8DBF C846 E47A
PGP D-H fingerprint = 98BC 65E3 1A19 43EC 3908 65B9 F755 E6F4 63BB 9D93
The five most dangerous words in the English language:
               "There oughta be a law"

Boost list run by bdawes at, gregod at, cpdaniel at, john at