2010-10-26 62 views
3

我有MacOS X上的Python 2.6和多线程操作。下面的测试代码工作正常,并关闭应用程序上按Ctrl-C:Python在多线程程序中忽略SIGINT - 如何解决这个问题?

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) 

但是,如果我只能改变一个字符串,加入一些实际工作,以工作线程,应用程序将永远不会在按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) 

是否可以修复它,或python不打算与线程一起使用?

+0

我更新了我的答案。 – 2010-10-26 22:45:16

回答

2

一对夫妇的事情,可能会导致您的问题:

  1. 按Ctrl-C也许是被抓svn,这是忽略它。
  2. 您正在创建一个非守护线程的线程,然后退出该进程。这将导致进程等到线程退出 - 它永远不会。你需要使线程成为一个守护进程,或者给它一个终止它的方法,并且在退出前给它一个join()。虽然它似乎总是停止在我的Linux系统上,但MacOS X的行为可能会有所不同。

Python的作品不够用线程:-)

更新:你可以尝试使用subprocess,建立子进程,使文件句柄不能被继承,并设置孩子的标准输入到子进程。管。

+0

“Ctrl- C可能被svn捕获,而忽略它“ - 非常有趣。是否有什么办法可以从我的python代码启动”svn up“,所以输入是python而不是svn? – grigoryvp 2010-10-26 13:58:26

2

我不是Python专家,但很快就读了文档,得出了一些结论。

1)调用os.system()会产生一个新的子shell,不鼓励。相反,应该使用子流程模块。 http://docs.python.org/release/2.6.6/library/os.html?highlight=os.system#os.system

2)threading模块似乎并没有给一大堆控制的线程,也许尝试使用thread模块,至少有一个thread.exit()功能。同样来自threading文档here它说,虚拟线程可以创建的,它总是活和后台,而且

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

所以,我会想象,至少你需要做的是信号当前正在运行的线程,他们在退出主线程之前需要退出,或者在ctrl-c上加入它们以允许它们完成(虽然这显然与ctrl-c相矛盾),或者可能只是使用subprocess模块来产生svn up就可以做到这一点。

+0

“线程模块似乎没有给予线程很多控制,也许尝试使用线程模块” - “线程”基于'线程',它们实际上是相同的:( – grigoryvp 2010-10-26 10:37:33

2

您可能根本不需要线程。

尝试使用Python的subprocess模块,或者甚至Twisted的process support