开发者

Python ignores SIGINT in multithreaded programs - how to fix that?

I have Python 2开发者_开发技巧.6 on MacOS X and a multithread operation. Following test code works fine and shuts down app on Ctrl-C:

import threading, time, os, sys, signal
def SigIntHandler( signum, frame ) :
  sys.exit( 0 )
signal.signal( signal.SIGINT, SigIntHandler )
class WorkThread( threading.Thread ) :
  def run( self ) :
    while True :
      time.sleep( 1 )
thread = WorkThread()
thread.start()
time.sleep( 1000 )

But if i change only one string, adding some real work to worker thread, the app will never terminate on Ctrl-C:

import threading, time, os, sys, signal
def SigIntHandler( signum, frame ) :
  sys.exit( 0 )
signal.signal( signal.SIGINT, SigIntHandler )
class WorkThread( threading.Thread ) :
  def run( self ) :
    while True :
      os.system( "svn up" ) # This is really slow and can fail.
      time.sleep( 1 )
thread = WorkThread()
thread.start()
time.sleep( 1000 )

Is it possible to fix it, or python is not intended to be used with threading?


A couple of things which may be causing your problem:

  1. The Ctrl-C is perhaps being caught by svn, which is ignoring it.
  2. You are creating a thread which is a non-daemon thread, then just exiting the process. This will cause the process to wait until the thread exits - which it never will. You need to either make the thread a daemon or give it a way to terminate it and join() it before exiting. While it always seems to stop on my Linux system, MacOS X behaviour may be different.

Python works well enough with threads :-)

Update: You could try using subprocess, setting up the child process so that file handles are not inherited, and setting the child's stdin to subprocess.PIPE.


You likely do not need threads at all.

Try using Python's subprocess module, or even Twisted's process support.


I'm not an expert on Threads with Python but quickly reading the docs leads to a few conclusions.

1) Calling os.system() spawns a new subshell and is not encouraged. Instead the subprocess module should be used. http://docs.python.org/release/2.6.6/library/os.html?highlight=os.system#os.system

2) The threading module doesn't seem to give a whole lot of control to the threads, maybe try using the thread module, at least there is a thread.exit() function. Also from the threading docs here it says that dummy threads may be created, which are always alive and daemonic, furthermore

"… the entire Python program exits when only daemon threads are left."

So, I would imagine that the least you need to do is signal the currently running threads that they need to exit, before exiting the main thread, or joining them on ctrl-c to allow them to finish (although this would obviously be contradictory to ctrl-c), or perhaps just using the subprocess module to spawn the svn up would do the trick.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜