102 lines
3.2 KiB
Plaintext
102 lines
3.2 KiB
Plaintext
From: jeremy at cnri.reston.va.us (Jeremy Hylton)
|
|
Date: Tue, 27 Apr 1999 12:01:22 -0400 (EDT)
|
|
Subject: threading/events questions
|
|
In-Reply-To: <3725a47f.96308574@scout>
|
|
References: <3725a47f.96308574@scout>
|
|
Message-ID: <14117.54695.658787.508940@bitdiddle.cnri.reston.va.us>
|
|
Content-Length: 2934
|
|
X-UID: 460
|
|
|
|
>>>>> "C" == Chris <sca at isogmbh.de> writes:
|
|
|
|
C> Hello... After experimenting with the modules thread and
|
|
C> threading I have some open questions. I've written the famous
|
|
C> ping-pong program.
|
|
|
|
I'm not familiar with the ping-pong problem in general. I wonder if
|
|
the code you posted is doing exactly what you intended. The event
|
|
you're using could be used to allow communicate/synchronization
|
|
between the threads, but instead it's being used to sleep; the
|
|
Quit.wait() call only returns after the timeout period. So you could
|
|
just as easily call sleep:
|
|
|
|
def f(t, msg):
|
|
print msg
|
|
## Quit.wait(t)
|
|
## if Quit.isSet():
|
|
## return
|
|
time.sleep(t)
|
|
f(t, msg)
|
|
|
|
You could also replace the recursive function call with a loop:
|
|
|
|
def f(t, msg):
|
|
while 1:
|
|
print msg
|
|
Quit.wait(t)
|
|
if Quit.isSet():
|
|
break
|
|
|
|
C> With that program, the threads are running for 60 seconds. But,
|
|
C> how can I stop one thread and not both? I don't want to write an
|
|
C> additional function doing exactly the same except dealing with a
|
|
C> different Event.
|
|
|
|
You could make the event a parameter instead of a global variable:
|
|
|
|
def f(timeout, event, msg):
|
|
print msg
|
|
event.wait(timeout)
|
|
if event.isSet():
|
|
return
|
|
f(timeout, event, msg)
|
|
|
|
C> My second problem is sending an event with a message.
|
|
C> ChangeOutput = Event() and send the event ChangeOutput('something
|
|
C> different than ping-pong') to one thread. After receiving this
|
|
C> message, the thread should change the recursive call to f(t,
|
|
C> 'something different, than ping-pong').
|
|
|
|
Event objects don't have associated messages be default. You would
|
|
need to create a new object that also had an associated message.
|
|
|
|
You could create an object that has the functionality you're
|
|
interested in and an associated event. You could manage the two
|
|
separately, although it seems like you do less bookkeeping if the
|
|
object has the event as an instance variable. Not sure if there are
|
|
pitfalls lurking...
|
|
|
|
import threading
|
|
class MessageHolder(threading._Event):
|
|
def __init__(self, msg):
|
|
threading._Event.__init__(self)
|
|
self.msg = msg
|
|
def set_msg(self, msg):
|
|
self.msg = msg
|
|
self.set()
|
|
def get_msg(self):
|
|
return self.msg
|
|
|
|
def f2(timeout, msg_obj):
|
|
while 1:
|
|
print msg_obj.get_msg()
|
|
msg_obj.wait(timeout)
|
|
if msg_obj.isSet():
|
|
msg_obj.clear()
|
|
|
|
C> How can I wait for events (more than one)? In the code above,
|
|
C> I am just waiting for one event with a proper timeout. How can I
|
|
C> react on the additional event ChangeOutput?
|
|
|
|
Good question! I don't have a good answer. You might have some
|
|
arrangement with hierarchical events (or conditions), so that one
|
|
event is set only when one of the events under it is set. So you can
|
|
wait on the upper event, and when it is set, check each of the
|
|
underlying events.
|
|
|
|
Jeremy
|
|
|
|
|
|
|
|
|