[Tutor] Variables in Threaded functions

lonetwin lonetwin@yahoo.com
Fri, 12 Oct 2001 15:38:35 +0530


Hi everybody,
    Thanx Boudewijn, for the quick answer. Now that I have fixed what I was 
trying to do...I have some more questions for you (an' everybody who might 
want to answer).
     You wrote:
> If you want all threads to share something, you do need to have an
> object that is accessible to all of them. However, accessing a shared
> object from more than one thread at a time is a recipe for disaster,
> so you need to create a lock object, and acquire() that lock before
> every access.
   Right, I though as much.
*********************************************
> This is how I rewrote your script:
> ----
> import threading, time
>
> class Strand(threading.Thread):
>
>     def __init__(self, bag, lock):
>         """The bag and the lock are shared objects,
>         passed to the threads in their constructors. Another
>         strategy is to make them global, but that's not half
>         as neat."""
>         threading.Thread.__init__(self)
>         self.bag=bag
>         self.lock=lock
<-------------------------snip-------------------------->
 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

class Strand(threading.thread):
    bag = range(100)
    def __init__(self, lock):
        .....
        .....
<-------------------------/snip---------------------------->
>     def run(self):
>         # getName() tells us which thread is started
>         print "Started " + self.getName()
>         # We keep running until something gives us a break
>         while 1:
>             # We acquire the lock - in Java objects can be their own
>             # locks, and you can synchronize() on an object. In Python
>             # you need a separate lock object, and explicitly
>             # acquire() that lock. If one thread accesses the
>             # resources the lock is supposed to protect, without
>             # acquiring it, then your concurrency is hosed. Caveat
>             # delendor.
>             self.lock.acquire()
>             # Always encapsulate usage of the locked object in a
>             # try... finally block: if the lock isn't released through
>             # some exception, all other threads would be blocked.
>             try:
>                 # If the bag is empty, we quit.
>                 if len(self.bag) == 0:
>                     break
>                 # Print the popped value
>                 print "thread", self.getName(), ": ", self.bag.pop()
>             finally:
>                 # Whatever happens, always release the lock.
>                 self.lock.release()

<----------------------snip-------------------------------->
 Question 2: Why ....

def run(self):
    while 1:
        self.acquire()
        try:
            if len(self.bag) == 0:
                break
            else:
                doStuff()
         finally:
            self.lock.release()
     .......

instead of ....

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 ???
<---------------------------/snip---------------------->
>             # Sleep a bit. A timeslice is long enough to pop the whole
>             # bag in the first timeslice of the first thread.
>             time.sleep(1)
>
> def main():
>     Rope = []
>     # The shared object and the shared lock
>     sharedBagOfGoodies = range(100)
>     sharedBagLock = threading.Lock()
>
>     for x in range(3):
>         thread = Strand(sharedBagOfGoodies, sharedBagLock)
>         Rope.append(thread)
>
>     for thread in Rope:
>         print thread.getName()
>         thread.start()
>
>     print "done"
>
> if __name__ == '__main__':
>     main()
> -------

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

Peace
Steve
----------------------------------------------
Every oak tree started out as a 
couple of nuts who stood their ground.
                                    Anonymous
----------------------------------------------