2010-10-26 2 views
3

У меня Python 2.6 на MacOS X и многопоточная операция. После тестирования кода отлично работает и выключается приложение на 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) 

Можно ли исправить это, или питон не предназначен для использования с резьбой?

+0

Я обновил свой ответ. –

ответ

2

Несколько вещей, которые могут быть причиной вашей проблемы:

  1. Сочетание клавиш Ctrl-C, возможно, будучи пойманной svn, который игнорирует его.
  2. Вы создаете поток, который является потоком не-демона, а затем просто выходит из процесса. Это заставит процесс ждать, пока поток не выйдет - чего он никогда не будет. Вам нужно либо сделать поток демонами, либо дать ему способ его прекратить, и join() перед его выходом. Несмотря на то, что он всегда останавливается в моей системе Linux, поведение MacOS X может быть другим.

Python работает достаточно хорошо с потоками :-)

Update: Вы можете попробовать использовать subprocess, создание дочернего процесса, так что файловые дескрипторы не наследуются, а настройка стандартного ввода ребенка подпроцесс. ТРУБЫ.

+0

«Ctrl- C, возможно, поймал svn, который игнорирует его »- очень интересно. Я могу начать« svn up »из моего кода на Python, поэтому вход идет на python, а не svn? – grigoryvp

2

Я не специалист по темам с Python, но быстрое чтение документов приводит к нескольким выводам.

1) Вызов os.system() порождает новую подоболочку и не поощряется. Вместо этого следует использовать модуль подпроцесса. 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

«Потолочный модуль, похоже, не дает большого контроля над потоками, возможно, попробуйте использовать модуль потока» - 'threading' основан на' thread', они на самом деле одинаковы :( – grigoryvp

2

Вероятно, вам не нужны нитки.

Попробуйте использовать модуль subprocess Python или даже Twisted's process support.

Смежные вопросы