views:

94

answers:

4

I have a long process that i've scheduled to run in a thread, because otherwise it will freeze the ui in my wxpython application.

I'm using

threading.Thread(target = myLongProcess).start()

to start the thread and it works, but I don't know how to pause and resume the thread. I looked in the python docs for the above methods, but wasn't able to find them.

Could anyone suggest how I could do this?

Thank you.

+1  A: 

You can use signals: http://docs.python.org/library/signal.html#signal.pause

To avoid using signals you could use a token passing system. If you want to pause it from the main UI thread you could probably just use a Queue.Queue object to communicate with it.

Just pop a message telling the thread the sleep for a certain amount of time onto the queue.

Alternatively you could simply continuously push tokens onto the queue from the main UI thread. The worker should just check the queue every N seconds (0.2 or something like that). When there are no tokens to dequeue the worker thread will block. When you want it to start again just start pushing tokens on to the queue from the main thread again.

dpn
No, you cannot send signals to a thread -- only to a process! And `signal.pause` only means the calling process sleeps until a signal is received -- no use for the OP's request. See my answer for the correct approach.
Alex Martelli
@Alex - thanks for the clarification. The signal part of my response was an afterthought.. cheers :)
dpn
A: 

There is no method for other threads to forcibly pause a thread (any more than there is for other threads to kill that thread) -- the target thread must cooperate by occasionally checking appropriate "flags" (a threading.Condition might be appropriate for the pause/unpause case).

If you're on a unix-y platform (anything but windows, basically), you could use multiprocessing instead of threading -- that is much more powerful, and lets you send signals to the "other process"; SIGSTOP should unconditionally pause a process and SIGCONT continues it (if your process needs to do something right before it pauses, consider also the SIGTSTP signal, which the other process can catch to perform such pre-suspension duties. (There may be ways to obtain the same effect on Windows, but I'm not knowledgeable about them, if any).

Alex Martelli
Unfortunately, I'm targeting windows, so I don't think i'll be able to use multiprocessing. I don't want one thread to pause another, I just want to send a message to the thread telling it to pause itself(or is this the same thing as telling one thread to pause another?), could that be done by tweaking the threading class?
jimbo
"Sending a message" can be done literally by a Queue, but (as I said) more practically for this case with a Condition. But the target thread must periodically check the Condition (or Queue) in order to **receive** the "messages": there is no way for you to "force" it to "receive the messages", you must _code_ it that way explicitly (likely w/a loop). There is no way for other threads to forcibly make a thread "receive messages meant for it", to cast my A's first sentence in the terms you appear to prefer. BTW, Windows does have a `SuspendThread` API (cont.)
Alex Martelli
For a Windows-specific solution, see http://msdn.microsoft.com/en-us/library/ms686345(VS.85).aspx -- you can call Windows APIs directly from Python with `ctypes` or http://sourceforge.net/projects/pywin32/ .
Alex Martelli
A: 

You might take a look at the Windows API for thread suspension.

As far as I'm aware there is no POSIX/pthread equivalent. Furthermore, I cannot ascertain if thread handles/IDs are made available from Python. There are also potential issues with Python, as its scheduling is done using the native scheduler, it's unlikely that it is expecting threads to suspend, particularly if threads suspended while holding the GIL, amongst other possibilities.

Matt Joiner
A: 

The multiprocessing module works fine on Windows. See the documentation here (end of first paragraph):

http://docs.python.org/library/multiprocessing.html

On the wxPython IRC channel, we had a couple fellows trying multiprocessing out and they said it worked. Unfortunately, I have yet to see anyone who has written up a good example of multiprocessing and wxPython.

If you (or anyone else on here) come up with something, please add it to the wxPython wiki page on threading here: http://wiki.wxpython.org/LongRunningTasks

You might want to check that page out regardless as it has several interesting examples using threads and queues


Mike Driscoll

Blog: http://blog.pythonlibrary.org

Mike Driscoll