nir1408
1/20/2008 1:30:00 PM
On Jan 19, 2:43 am, Matthew Wilson <m...@tplus1.com> 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
It does not check a different variable.
You can open a Python session and try the following:
Python 2.5.1 (r251:54863, Oct 5 2007, 13:36:32)
[GCC 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> a = True
>>> id(a)
135527852
>>> a = False
>>> id(a)
135527840
The problem is that the waiter is locked waiting for new food and
never looks at the variable.
You should add hot_food.release() after you set the keep running flag
to False.
Nir