[Tutor] Variables in Threaded functions

Kirby Urner urnerk@qwest.net
Fri, 12 Oct 2001 17:48:23 -0700

>  Question 1:  why is bag passed to Strand ??....what if
>I bag belongs to be the class ....like I did in my initial
>proggy ...is this a bad-thing in any manner vvvvvvvvvvv

Seems a non-idiomatic use of a class variable, but
maybe it works -- I haven't tested it.

>def run(self):
>     self.acquire()
>     try:
>         while len(self.bag) !=0:
>             doStuff()
>     finally:
>         self.lock.release()
>     For me, this ^^^^ reads much better....but is there something
>I should know about ???

Here your thread grabs the lock, then loops around while
the bag isn't empty, sucking it dry, then, finally, it
releases the lock.  So what do the other threads get to
do?  Just wait around and watch while Mr. Greedy Gut hogs
the entire bag I guess.

>And finally Question 3: What if I have more that one bag ??
>does one lock, lock-up all the shared objects ??....or should
>I lock.acquire() before every access to any one of the shared
>objects ??
>Hope my questions make sense...
>Thanx for you patience

Well, I'm not Mr. Threads (the previous respondant sounded
way more knowledgable than I), but I think you should think
of the lock as akin to the conch in 'Lord of the Flies'.
Every read that?  These kids get marooned on a tropical
island and their culture gradually degenerates, but one
convention is whoever holds this big shell in meetings is
the one who gets to talk, and you pass this shell (conch)
around to control the flow of speech -- similar to a
"talking stick" in some native American traditions.

The lock is a conch, and as long as one thread has it,
the other threads block when trying to aquire it for
themselves.  Whichever thread is holding the conch has
to explicitly release it, before the other would-be
aquirers have a chance.

However, as the previous respondant posted, it's up to
you to write civilized thread code that actually asks
permission before modifying data:

    If one thread accesses the resources the lock
    is supposed to protect, without acquiring it,
    then your concurrency is hosed. Caveat delendor.

You-the-programmer put into your code where a thread
should say "pretty please". But if you code up some
bull-in-a-China-shop thread that doesn't even ask
(doesn't try to aquire) but just goes ahead and attacks
the bag, then all the other threads can do is watch in
horror.  No operating system police are going to keep
the undisciplined thread from just charging around,
doing whatever damage.

In other words, the aquire(), release() convention
simply provides a mechanism whereby you can establish
a genteel arrangement among your threads, but doesn't
involve any physical placement of locks on any data
objects.  Ergo, there's no question of needing multiple
locks for each object -- they're not really locked,
it's the threads that use the lock object to take
turns doing whatever.


PS:  in 'Lord of the Flies', some bullies eventually
get tired of the conch convention and break this final
rule.  Some fat kid, who was holding the conch at the
time, protests, and pays with his life.  A cheery book
-- they make school kids read it so they can see why
adults are so strict (left to your own devices, you'd
make dead meat of each other in no time, is the message).