Уведомления

Группа в Telegram: @pythonsu

#1 Июль 8, 2014 14:10:05

koluna
Зарегистрирован: 2014-07-08
Сообщения: 30
Репутация: +  0  -
Профиль   Отправить e-mail  

Многопоточное приложение и Ctrl-C в терминале

Всем привет!

Python 2.7 (Windows, Linux).

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

Сделал в основном потоке:

try 
... 
except KeyboardInterrupt:
# Сообщение о завершении работы и завершение работы.
...

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

Офлайн

#2 Июль 8, 2014 14:16:12

Singularity
Зарегистрирован: 2011-07-28
Сообщения: 1387
Репутация: +  75  -
Профиль   Отправить e-mail  

Многопоточное приложение и Ctrl-C в терминале

может надо запуст потоков в блок try запихнуть?

Офлайн

#3 Июль 8, 2014 14:37:39

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

Многопоточное приложение и Ctrl-C в терминале

koluna
Но обнаружил, что исключение обрабатывается не всегда!
А как Вы это обнаружили?

Офлайн

#4 Июль 8, 2014 15:26:37

koluna
Зарегистрирован: 2014-07-08
Сообщения: 30
Репутация: +  0  -
Профиль   Отправить e-mail  

Многопоточное приложение и Ctrl-C в терминале

Singularity
может надо запуст потоков в блок try запихнуть?

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

Офлайн

#5 Июль 8, 2014 15:28:12

koluna
Зарегистрирован: 2014-07-08
Сообщения: 30
Репутация: +  0  -
Профиль   Отправить e-mail  

Многопоточное приложение и Ctrl-C в терминале

Shaman

Вывожу отладочные сообщения с помощью print или модуля logger в дочернем потоке и в “except KeyboardInterrupt” основного потока.

Офлайн

#6 Июль 8, 2014 15:29:46

koluna
Зарегистрирован: 2014-07-08
Сообщения: 30
Репутация: +  0  -
Профиль   Отправить e-mail  

Многопоточное приложение и Ctrl-C в терминале

Я пока не пойму как обрабывается Ctrl-C в многопоточном приложении.
Исключение KeyboardInterrupt приходит только основному потоку? Всем потокам? Или тому потоку, который в данный момент выполняется?

Офлайн

#7 Июль 8, 2014 15:49:57

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

Многопоточное приложение и Ctrl-C в терминале

Офлайн

#8 Июль 8, 2014 16:12:40

koluna
Зарегистрирован: 2014-07-08
Сообщения: 30
Репутация: +  0  -
Профиль   Отправить e-mail  

Многопоточное приложение и Ctrl-C в терминале

Прочитал разочек, но прозрения полного пока не наступило
У меня 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 программу завершает, но не выводится никаких сообщений…

Отредактировано koluna (Июль 8, 2014 17:07:11)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version