thread problem
Greg Wilson
gvwilson at nevex.com
Mon Feb 28 15:47:21 EST 2000
I'm trying to implement futures in Python using threads. When a future is
created, it (internally) spawns a thread to calculate its value. When
another thread tries to get the future's value (by calling the future
object as if it were a function), the read blocks until the value is
available.
My implementation is included below. The problem is that I'm setting
'self.result' in the child thread, but when the __call()__ returns, the
value has gone back to 'None'. There's nothing in the docs about objects
being cloned during thread creation --- I'd be grateful if anyone could tell
me what's up.
Thanks,
Greg
-----------------------
#!/usr/bin/python
from thread import *
import time
"""Simple future class for Python"""
class Future:
# Create the future.
def __init__(self):
# Setup code executed in creator's thread.
# Important that lock is locked before thread spawned.
self.result = None
self.lock = allocate_lock()
self.lock.acquire()
start_new_thread(Future._run, (self,))
# Run the thread evaluator.
def _run(self):
# Do the work defined by the derived class.
print `get_ident()` + \
" about to self.evaluate()"
self.result = self.evaluate()
print `get_ident()` + \
" returned from self.evaluate()" + \
" releasing lock" + \
" result is " + \
`self.result`
# Report.
self.lock.release()
print `get_ident()` + \
" released lock" + \
" result is " + \
`self.result`
# Fetch the future's value.
def __call__(self):
print `get_ident()` + \
" in __call__()" + \
" lock state is " + \
`self.lock.locked()`
# If the lock is still held...
if self.lock.locked():
# ...wait for evaluation to complete...
self.lock.acquire()
# ...then signal to others that the value is available
self.lock.release()
# Result must have been calculated by here.
print `get_ident()` + \
" returning self.result == " + \
`self.result`
return self.result
# Default version of 'evaluate()' does nothing
def evaluate(self):
pass
# Derive a future class that sleeps for a while, then returns a constant
class FutureTest(Future):
# Create the future
def __init__(self, constant):
self.constant = constant
Future.__init__(self)
# Calculate a value
def evaluate(self):
print `get_ident()` + \
" in derived evaluate()" + \
" constant is " + \
`self.constant` + \
" and result before call is " + \
`self.result`
print `get_ident()` + \
" passed sleep()" + \
" setting result in derived evaluate()"
self.result = self.constant
print `get_ident()` + \
" self.result is now " + \
`self.result`
# Test
if __name__ == "__main__":
# simple test function
print "\n\n" + `get_ident()` + ": creating future"
f = FutureTest(2)
print `get_ident()` + ": fetching value"
val = f()
print `get_ident()` + ": value is " + `val` + "\n\n"
More information about the Python-list
mailing list