Найти - Пользователи
Полная версия: Многопоточное приложение и Ctrl-C в терминале
Начало » Python для новичков » Многопоточное приложение и Ctrl-C в терминале
1
koluna
Всем привет!

Python 2.7 (Windows, Linux).

Написал простейшее многопоточное приложение.
Программа состоит из одного файла. В нем основной поток запускает дочерний поток (модуль threading).
Запускаю программу в терминале. Необходимо перехватить нажатие Ctrl-C, чтобы правильно завершить работу программы.

Сделал в основном потоке:
try 
... 
except KeyboardInterrupt:
# Сообщение о завершении работы и завершение работы.
...

При работе программы в разные моменты нажимаю Ctrl-C. Программа завершается. Но обнаружил, что исключение обрабатывается не всегда! Т. е., иногда мы попадаем в “except KeyboardInterrup”, а иногда не попадаем.
В чем может быть дело?
Singularity
может надо запуст потоков в блок try запихнуть?
Shaman
koluna
Но обнаружил, что исключение обрабатывается не всегда!
А как Вы это обнаружили?
koluna
Singularity
может надо запуст потоков в блок try запихнуть?

Он там и есть… но как это повлияет на решение моей задачи?
Поток ведь нормально запускается и работает…
koluna
Shaman

Вывожу отладочные сообщения с помощью print или модуля logger в дочернем потоке и в “except KeyboardInterrupt” основного потока.
koluna
Я пока не пойму как обрабывается Ctrl-C в многопоточном приложении.
Исключение KeyboardInterrupt приходит только основному потоку? Всем потокам? Или тому потоку, который в данный момент выполняется?
Shaman
Есть нюансы:
http://asvetlov.blogspot.ru/2011/07/signal.html
http://habrahabr.ru/post/84629/
koluna
Прочитал разочек, но прозрения полного пока не наступило
У меня join() вообще в finally стоит.
Т. е., я в главном потоке ловлю KeyboardInterrupt, выставляю event, жду join, дочерний поток проверяет этот event и если он установлен - выходим из функции потока.

В общем, код такой:
import threading
event = threading.Event()
def func(ev):
    while not ev.is_set():
        print 'Work.'
        a = 0
        for i in xrange(10000000):
            a += i
    ev.clear()            
    print 'Stopped!'
    
try:   
    thr = threading.Thread(target=func, args=(event, ))
    print 'Started.'
    thr.start()
    
    while True:
        pass
except KeyboardInterrupt:
    print 'Ctrl-C!!!'
    
finally:
    print 'End.'
    event.set()
    thr.join()

Это работает, но если в поток поместить что-то более емкое, допустим, работу с БД, то Ctrl-C программу завершает, но не выводится никаких сообщений…
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB