简体   繁体   English

Python在多线程程序中忽略了SIGINT - 如何解决这个问题?

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

I have Python 2.6 on MacOS X and a multithread operation. 我在MacOS X上有Python 2.6和多线程操作。 Following test code works fine and shuts down app on Ctrl-C: 以下测试代码正常工作并关闭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: 但是,如果我只更改一个字符串,向工作线程添加一些实际工作,应用程序永远不会在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? 是否可以修复它,或者python不适合与线程一起使用?

I'm not an expert on Threads with Python but quickly reading the docs leads to a few conclusions. 我不是Python的线程专家,但很快阅读文档会得出一些结论。

1) Calling os.system() spawns a new subshell and is not encouraged. 1)调用os.system()产生一个新的子shell,不鼓励。 Instead the subprocess module should be used. 而应该使用子进程模块。 http://docs.python.org/release/2.6.6/library/os.html?highlight=os.system#os.system 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. 2) threading模块似乎没有给threading提供大量的控制,也许尝试使用thread模块,至少有一个thread.exit()函数。 Also from the threading docs here it says that dummy threads may be created, which are always alive and daemonic, furthermore 同样来自这里threading文档它表示可以创建虚拟线程,此外,它们总是存活的和守护的

"… 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. 因此,我认为你需要做的最少是在退出主线程之前发出当前正在运行的线程的信号,或者在ctrl-c上加入它们以允许它们完成(尽管这显然是矛盾的ctrl-c),或者只是使用subprocess模块来生成svn up就可以了。

A couple of things which may be causing your problem: 可能导致您的问题的一些事情:

  1. The Ctrl-C is perhaps being caught by svn , which is ignoring it. Ctrl-C可能被svn捕获,而忽略了它。
  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. 你需要让线程成为一个守护进程,或者给它一个终止它的方法,并在退出之前join()它。 While it always seems to stop on my Linux system, MacOS X behaviour may be different. 虽然它似乎总是在我的Linux系统上停止,但MacOS X的行为可能会有所不同。

Python works well enough with threads :-) Python与线程运行良好:-)

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. 更新:您可以尝试使用subprocess进程,设置子进程以便不继承文件句柄,并将子进程的stdin设置为subprocess.PIPE。

You likely do not need threads at all. 你可能根本不需要线程。

Try using Python's subprocess module, or even Twisted's process support . 尝试使用Python的subprocess 进程模块,甚至是Twisted的进程支持

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM