Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Pausing and Unpausing Threads

Reply
Thread Tools

Pausing and Unpausing Threads

 
 
Aaron J. M.
Guest
Posts: n/a
 
      08-12-2007
Hello,

This is a question about how to pause and unpause threads (as the
title suggests).

I've created an extension of threading.Thread which I'll call Server.
Server has a collection of Controlers. A Controler has a method
turn(), which lets it do various interesting things. While the
Server is running, it loops through each of its Controlers and calls
their turn() method.

One of these Controlers is a subclass called DirectedControler.
What a DirectedControler is meant to do is wait until it is given an
Action object it can invoke. Actions are basically an implementation
of the Command pattern. Actions are also invalid in certain
circumstances; they return False when executed if they didn't do
anything. Therefore, when a DirectedControler is given a turn, it
waits while:
- It has no Action
- The last Action it was given didn't do anything

Actions are sent to the DirectedControler by a Client that exists in
the main thread.

What I'm trying to figure out is how to make the DirectedControler
pause while it is waiting for a valid Action. So far I just put it
into a loop like this:

def turn(self):
while self.__action is None or not self.__action.execute():
self.__action = None # Throw away invalid actions
pass

self.__action = None # Action was valid. Clear the way for the
# next turn's Action.

Where the Action is set like this (by the Client):

def setAction(self, action):
if self.__action is None:
self.__action = action

I'm worried that this loop may wast some CPU cycles, and wonder if
there's a better way through thread synchronization using such things
as Events or Conditions.

Thank you,

Aaron J. M.

 
Reply With Quote
 
 
 
 
=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=
Guest
Posts: n/a
 
      08-12-2007
> I'm worried that this loop may wast some CPU cycles, and wonder if
> there's a better way through thread synchronization using such things
> as Events or Conditions.


Typically, people are after the Queue module in such cases. Each
DirectedControl(l)er would have an instance of the Queue class,
and clients would put() actions into the queue. The controller would
get() an action from the queue, execute it, get the next action,
and so on. The get() will block when the queue is empty, so you
get synchronization for free. The queue would also accommodate the
case where multiple clients want to direct the same controller
simultaneously, by, well, queuing up the tasks.

HTH,
Martin
 
Reply With Quote
 
 
 
 
Dennis Lee Bieber
Guest
Posts: n/a
 
      08-12-2007
On Sat, 11 Aug 2007 18:46:16 -0700, "Aaron J. M."
<(E-Mail Removed)> declaimed the following in comp.lang.python:

> Hello,
>
> This is a question about how to pause and unpause threads (as the
> title suggests).
>
> I've created an extension of threading.Thread which I'll call Server.
> Server has a collection of Controlers. A Controler has a method
> turn(), which lets it do various interesting things. While the
> Server is running, it loops through each of its Controlers and calls
> their turn() method.
>
> One of these Controlers is a subclass called DirectedControler.
> What a DirectedControler is meant to do is wait until it is given an
> Action object it can invoke. Actions are basically an implementation
> of the Command pattern. Actions are also invalid in certain
> circumstances; they return False when executed if they didn't do
> anything. Therefore, when a DirectedControler is given a turn, it
> waits while:
> - It has no Action
> - The last Action it was given didn't do anything
>

By this definition, if there is no "action" supplied, a
"DirectedControler" will result in blocking ALL others (directed or not)
in this "server" (as it blocks the entire server thread).

Is that really the behavior you want?

> Actions are sent to the DirectedControler by a Client that exists in
> the main thread.
>
> What I'm trying to figure out is how to make the DirectedControler
> pause while it is waiting for a valid Action. So far I just put it
> into a loop like this:
>
> def turn(self):
> while self.__action is None or not self.__action.execute():
> self.__action = None # Throw away invalid actions
> pass


That "pass" is useless.
>
> self.__action = None # Action was valid. Clear the way for the
> # next turn's Action.
>
> Where the Action is set like this (by the Client):
>
> def setAction(self, action):
> if self.__action is None:
> self.__action = action
>

Possible race condition -- what happens if "turn()" is just starting
to process the previous "action", so self.__action is not None. The
client code will then skip doing anything. [Also note that if you want
to indicate that an attribute is supposed to be considered private, the
convention is for ONE _, not two -- two _ sets up name mangling in
inheritance trees]

I'd suggest using a Queue PER directed controller. Initialize

self._actions = Queue.Queue()

-=-=-=-=-=-

def turn(self):
while True:
atn = self._actions.get() #blocks until at least one entry
if atn and atn.execute(): #should be in a try/except if
# action has NO execute method
break #did something, so exit while

-=-=-=-=-=-

def setAction(self, action):
self._actions.put(action) #could add code to ensure
#an execute attribute

--
Wulfraed Dennis Lee Bieber KD6MOG
http://www.velocityreviews.com/forums/(E-Mail Removed) (E-Mail Removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (E-Mail Removed))
HTTP://www.bestiaria.com/
 
Reply With Quote
 
Aaron J. M.
Guest
Posts: n/a
 
      08-12-2007
On Aug 12, 3:55 pm, Dennis Lee Bieber <(E-Mail Removed)> wrote:
> By this definition, if there is no "action" supplied, a
> "DirectedControler" will result in blocking ALL others (directed or not)
> in this "server" (as it blocks the entire server thread).
>
> Is that really the behavior you want?


For my particular application, yes. This is exactly what I want.

> I'd suggest using a Queue PER directed controller. Initialize
>
> self._actions = Queue.Queue()
>
> -=-=-=-=-=-
>
> def turn(self):
> while True:
> atn = self._actions.get() #blocks until at least one entry
> if atn and atn.execute(): #should be in a try/except if
> # action has NO execute method
> break #did something, so exit while
>
> -=-=-=-=-=-
>
> def setAction(self, action):
> self._actions.put(action) #could add code to ensure
> #an execute attribute


Thank you very much for your help. I'll get to work on this now.

Cheers,

Aaron J. M.

 
Reply With Quote
 
Aaron J. M.
Guest
Posts: n/a
 
      08-13-2007
Uhg, I thought of something I didn't consider before: how to cleanly
end the Server/DirectedControl(l)er process. Assuming that the Client
only sends Actions to the DirectedController while the
DirectedController is in its turn() method (which I would probably
regulate using some flag in DirectedController) the Client will
eventually need a way to order the Server to stop its processing.
Stopping the Server also has to make the DirectedController break out
of its turn method without letting it execute an Action. I don't want
to just kill the Server thread because I may want to do serialization
or other kinds of cleanup.

Have people encountered something like this before?

Thank you,

Aaron J. M.

 
Reply With Quote
 
Gabriel Genellina
Guest
Posts: n/a
 
      08-13-2007
En Sun, 12 Aug 2007 21:45:47 -0300, Aaron J. M. <(E-Mail Removed)>
escribi�:

> Uhg, I thought of something I didn't consider before: how to cleanly
> end the Server/DirectedControl(l)er process.


Use the same Queue; put a special kind of Action, or just a None object,
to tell the thread that there are no more things to process.
From the main thread, you can join() the others, waiting for them to
finish.

--
Gabriel Genellina

 
Reply With Quote
 
Aaron J. M.
Guest
Posts: n/a
 
      08-13-2007
On Aug 13, 2:31 am, "Gabriel Genellina" <(E-Mail Removed)>
wrote:
> Use the same Queue; put a special kind of Action, or just a None object,
> to tell the thread that there are no more things to process.
> From the main thread, you can join() the others, waiting for them to
> finish.


Ah, thank you very much.

- Aaron J. M.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Pausing and continuing MFC Thread Lucress Carol C++ 3 09-16-2008 05:15 PM
Wireless keeps pausing =?Utf-8?B?Q3VydF9DIFtNVlBd?= Wireless Networking 0 10-20-2005 01:57 AM
Pausing a program - poll/sleep/threads? Simon John Python 12 02-21-2005 12:52 AM
Pausing Threads From Events Bryan R. Meyer Java 16 04-30-2004 12:57 AM
DVD Stuttering and pausing David Geesaman DVD Video 8 11-18-2003 12:30 PM



Advertisments