This is what's happening: 1) The chef thread releases the sema 2) While the chef thread is saying "Andiamo", decreasing "i", and ending the while loop, the waiter thread SERVES the dish and RUNS to reacquire the lock 3) Back in the main loop, chef.join() is run, and then the waiter's variable is changed.
But it's already too late. The waiter is already locked. He'll wait and wait forever for another dish, which will never come. So you will have to kill him. All for a race condition. --- I've just read Carl's post (just b4 hitting submit). I agree with him, rewrite the logic. IMO, the objects should be the key, THEY are the ones that should be joined. You should run the chef and waiter as daemons, and just do something like orders.join() dishes.join() And when the chefs finishes with the orders and the waiter finishes serving them, the program ends. HTH, Sergio On Jan 18, 2008 7:43 PM, Matthew Wilson <[EMAIL PROTECTED]> wrote: > In this code, I tried to kill my thread object by setting a variable on it > to False. > > Inside the run method of my thread object, it checks a different > variable. > > I've already rewritten this code to use semaphores, but I'm just curious > what is going on. > > Here's the code: > > import logging, threading, time > logging.basicConfig(level=logging.DEBUG, > format="%(threadName)s: %(message)s") > > class Waiter(threading.Thread): > def __init__(self, hot_food): > super(Waiter, self).__init__() > self.should_keep_running = True > self.hot_food = hot_food > > def run(self): > while self.should_keep_running: > logging.debug("Inside run, the id of should_keep_running is %s." > % id(self.should_keep_running)) > self.hot_food.acquire() > > def cook_food(hot_food): > i = 5 > while i >= 0: > logging.debug("I am cooking food...") > time.sleep(1) > hot_food.release() > logging.debug("Andiamo!") > i -= 1 > > def main(): > > hot_food = threading.Semaphore(value=0) > > chef = threading.Thread(name="chef", target=cook_food, args=(hot_food, )) > chef.start() > > w = Waiter(hot_food) > logging.debug("Initially, the id of w.should_keep_running is %s." > % id(w.should_keep_running)) > w.start() > logging.debug("After start, the id of w.should_keep_running is %s." > % id(w.should_keep_running)) > > # Wait for the chef to finish work. > chef.join() > > # Now try to kill off the waiter by setting a variable inside the waiter. > w.should_keep_running = False > logging.debug("Now, the id of w.should_keep_running is %s." > % id(w.should_keep_running)) > > if __name__ == "__main__": > main() > > And here's what I get when I execute it. I have to suspend the process > with CTRL=Z and then kill -9 it. > > $ python foo.py > MainThread: Initially, the id of w.should_keep_running is 135527852. > MainThread: After start, the id of w.should_keep_running is 135527852. > chef: I am cooking food... > Thread-1: Inside run, the id of should_keep_running is 135527852. > chef: Andiamo! > chef: I am cooking food... > Thread-1: Inside run, the id of should_keep_running is 135527852. > chef: Andiamo! > chef: I am cooking food... > Thread-1: Inside run, the id of should_keep_running is 135527852. > chef: Andiamo! > chef: I am cooking food... > Thread-1: Inside run, the id of should_keep_running is 135527852. > chef: Andiamo! > chef: I am cooking food... > Thread-1: Inside run, the id of should_keep_running is 135527852. > chef: Andiamo! > chef: I am cooking food... > Thread-1: Inside run, the id of should_keep_running is 135527852. > chef: Andiamo! > Thread-1: Inside run, the id of should_keep_running is 135527852. > MainThread: Now, the id of w.should_keep_running is 135527840. > > [1]+ Stopped python foo.py > > $ kill -9 %1 > > [1]+ Stopped python foo.py > > The memory address of should_keep_running seems to change when I set it > from True to False, and inside the run method, I keep checking the old > location. > > I am totally baffled what this means. > > Like I said earlier, I already rewrote this code to use semaphores, but > I just want to know what is going on here. > > Any explanation is welcome. > > TIA > > Matt > -- > http://mail.python.org/mailman/listinfo/python-list > -- http://mail.python.org/mailman/listinfo/python-list