Python在多线程程序中忽略SIGINT-如何修复?

Python在多线程程序中忽略SIGINT-如何修复?,python,Python,我有MacOS X上的Python2.6和一个多线程操作。以下测试代码工作正常,并关闭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

我有MacOS X上的Python2.6和一个多线程操作。以下测试代码工作正常,并关闭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 )
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 )
但是,如果我只更改一个字符串,向worker线程添加一些实际工作,应用程序将永远不会在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 )
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 )

有没有可能修复它,或者python不打算与线程一起使用?

我不是python线程方面的专家,但快速阅读文档可以得出一些结论

1) 调用
os.system()
会产生一个新的子shell,不鼓励这样做。相反,应该使用子流程模块

2)
threading
模块似乎没有给线程提供太多的控制,可以尝试使用
thread
模块,至少有一个
thread.exit()
函数。另外,从
threading
文档中可以看出,可以创建虚拟线程,而且虚拟线程始终是活动的、后台的

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

因此,我可以想象,您至少需要向当前运行的线程发出信号,指出它们需要退出,然后再退出主线程,或者在ctrl-c上加入它们以允许它们完成(尽管这显然与ctrl-c相矛盾),或者仅仅使用
子流程
模块生成
svn up
就可以解决问题。

可能会导致您出现问题的几件事:


  • Ctrl-C可能被
    svn
    捕获,而svn忽略了它
  • 您正在创建一个非守护进程线程,然后退出该进程。这将导致进程等待线程退出—它永远不会退出。您需要将该线程设置为守护进程,或者在退出之前为其提供一种终止它并加入()的方法。虽然它似乎总是在我的Linux系统上停止,但MacOS X的行为可能会有所不同
  • Python在线程方面工作得足够好:-)


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

    您可能根本不需要线程


    尝试使用Python的
    子进程
    模块,甚至Twisted模块。

    “线程模块似乎没有给线程提供太多的控制,也许可以尝试使用线程模块”-
    线程
    基于
    线程
    ,它们实际上是相同的:(“可能是svn捕获了Ctrl-C,而svn忽略了它”-非常有趣。我是否可以从我的python代码启动“svn-up”,以便输入到python,而不是svn?