Python多处理atexit错误“atexit._run_exitfuncs中的错误”

时间:2009-05-19 15:13:33

标签: python process interrupt atexit

我正在尝试在Python中运行一个简单的多进程应用程序。主线程产生1到N个进程并等待它们都完成处理。每个进程都运行一个无限循环,因此它们可以在没有用户中断的情况下永远运行,因此我输入了一些代码来处理KeyboardInterrupt:

#!/usr/bin/env python
import sys
import time
from multiprocessing import Process

def main():
    # Set up inputs..

    # Spawn processes
    Proc( 1).start()
    Proc( 2).start()

class Proc ( Process ):
    def __init__ ( self, procNum):
        self.id = procNum
        Process.__init__(self)

    def run ( self ):
        doneWork = False

        while True:

            try:
                # Do work...
                time.sleep(1)
                sys.stdout.write('.')

                if doneWork:
                    print "PROC#" + str(self.id) + " Done."
                    break

            except KeyboardInterrupt:
                print "User aborted."
                sys.exit()

# Main Entry
if __name__=="__main__":
    main()

问题是当使用CTRL-C退出时,即使进程似乎立即退出,我也会收到其他错误:

......User aborted.
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
  File "C:\Python26\lib\atexit.py", line 24, in _run_exitfuncs
    func(*targs, **kargs)
  File "C:\Python26\lib\multiprocessing\util.py", line 281, in _exit_function
    p.join()
  File "C:\Python26\lib\multiprocessing\process.py", line 119, in join
    res = self._popen.wait(timeout)
  File "C:\Python26\lib\multiprocessing\forking.py", line 259, in wait
    res = _subprocess.WaitForSingleObject(int(self._handle), msecs)
KeyboardInterrupt
Error in sys.exitfunc:
Traceback (most recent call last):
  File "C:\Python26\lib\atexit.py", line 24, in _run_exitfuncs
    func(*targs, **kargs)
  File "C:\Python26\lib\multiprocessing\util.py", line 281, in _exit_function
    p.join()
  File "C:\Python26\lib\multiprocessing\process.py", line 119, in join
    res = self._popen.wait(timeout)
  File "C:\Python26\lib\multiprocessing\forking.py", line 259, in wait
    res = _subprocess.WaitForSingleObject(int(self._handle), msecs)
KeyboardInterrupt

我在Windows上运行Python 2.6。如果有更好的方法来处理Python中的多处理,请告诉我。

2 个答案:

答案 0 :(得分:1)

而不是强制sys.exit(),你想要向你的线程发送一个信号告诉他们停止。查看在Python中使用signal handlers和线程。

您可以通过将while True:循环更改为while keep_processing:来实现此目的,其中keep_processing是某种在KeyboardInterrupt异常上设置的全局变量。我认为这不是一个好习惯。

答案 1 :(得分:1)

这是一个非常古老的问题,但似乎接受的答案实际上并没有解决问题。

主要问题是您还需要在父进程中处理键盘中断。除此之外,在 while 循环中,您只需要退出循环,无需调用 sys.exit()

我试图与原始问题中的示例紧密匹配。 doneWork 代码在示例中没有任何作用,因此为了清楚起见将其删除。

import sys
import time
from multiprocessing import Process


def main():
    # Set up inputs..

    # Spawn processes
    try:
        processes = [Proc(1), Proc(2)]
        [p.start() for p in processes]
        [p.join() for p in processes]
    except KeyboardInterrupt:
        pass


class Proc(Process):
    def __init__(self, procNum):
        self.id = procNum
        Process.__init__(self)

    def run(self):
        while True:
            try:
                # Do work...
                time.sleep(1)
                sys.stdout.write('.')

            except KeyboardInterrupt:
                print("User aborted.")
                break


# Main Entry
if __name__ == "__main__":
    main()