Python Multiprocessing atexit Error Ошибка в atexit._run_exitfuncs

Я пытаюсь запустить простое приложение с несколькими процессами в 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

Я использую Python 2.6 в Windows. Если есть лучший способ обработки многопроцессорности в Python, дайте мне знать.


person Community    schedule 19.05.2009    source источник


Ответы (1)


Вместо того, чтобы просто форсировать sys.exit(), вы хотите отправить сигнал своим потокам, чтобы сказать им, чтобы они остановились. Изучите использование обработчиков сигналов и потоков в Python.

Потенциально вы можете сделать это, изменив цикл while True: на while keep_processing:, где keep_processing — это какая-то глобальная переменная, которая устанавливается в исключении KeyboardInterrupt. Хотя я не думаю, что это хорошая практика.

person Jason Coon    schedule 19.05.2009
comment
Если возможно, можете ли вы добавить работающий пример этого решения. - person cmcginty; 08.07.2009
comment
Также ищу разработку по использованию обработчиков сигналов - person Tian; 20.08.2020