Найти - Пользователи
Полная версия: Не работает sys.exit(1)
Начало » Python для новичков » Не работает sys.exit(1)
1
pal201
Есть функция выхода:
def sys_exit():
print u'Работа программы завершена...'
sys.exit(1)
Так вот программа, после ее вызова не завершается. Выводит принт и все.
Приходится использовать:
os.kill(0,signal.SIGKILL)
В чем может быть дело?
система ubuntu…10, до этого была 9, то же самое.
Спасибо.
Андрей Светлов
Возможно, у вас остался работающий non-daemon thread.
pal201
Совершенно верно, потоки есть. Но у потоков нет метода их завершения, на сколько я понял. После запуска run поток будет вполняться неограниченно долго.
А если потоков еще не запущено, то sys.exit вообще ничего не делает. Странно это как-то
pal201
Вроде как после завершения родительского процесса все потоки должны завершаться? что-то этого не наблюдается…. Хочется услышать мнение профессионалов на этот счет.
Андрей Светлов
Давайте сначала о sys.exit.
Вызов этой функции просто выбрасывает исключение SystemExit.
Которое обычно не ловится пользовательским кодом, а выпадает наружу, где и обрабатывается как завершение процесса.

Теперь о потоках.
Они бывают daemon и не daemon.
Обычные - не демоны. Они должны закончиться перед завершением программы. Питон будет их ждать, если нужно.
threading.Thread API не имеет метода “прибить поток”, и это правильно. Принудительное завершение потока не может быть безопасным по определению.
По правильному это делается через установку флага/события или еще чего нибудь, на что поток должен ответить завершением. А после установки флажка - дождаться через .join()

Поток можно переключить через setDaemon(True) перед стартом. Запущенный поток сделать демоном нельзя.
Питон не ожидает завершения демонов при финише.
Несмотря на кажущуюся привлекательность сильно не рекомендую их использовать.
Первое: как правило, демоны - признак плохого дизайна. Незамутненный “код с душком” по Фаулеру.
Вторая причина прозаичней и веселее. Потоки-демоны живут еще чуть-чуть после завершения главного потока. Сколько - заранее не скажешь. Просто планировщик может успеть сделать несколько переключений на них. И окружение в это время наполовину разрушено. Т.е. может уже не быть каких-нибудь модулей или глобальных объектов. В результате поток уваливается на какой-нибудь весьма странной ошибке. Которая еще и не воспроизводится стабильно.

Резюме: за своими потоками нужно следить. Если создал поток - всегда дождись его .join() Если поток нужно прервать - выставляй сигнал и анализируй его внутри потока. Отступления от правил караются средой исполнения.
PooH
Андрей, вы не думали книгу написать? Все время интересные места выбираете и излагаете ясно.
Андрей Светлов
Книгу писать - это вам не на форуме языком молоть.
Всерьез - не думал.
Zubchick
напишите методичку :)
У вас отличное знание внутренностей, тем кто с питоном уже на ты, будет приятно узнать о том как это работает, а то большиснтво книг дают такое среднеповерхностное знание об этом.
Андрей Светлов
А вы читайте исходники перед сном. Чужие, разумеется - на чтении своих научиться невозможно.
У CPython, к слову, довольно простой и понятный код. В отличие от многих питонячьих библиотек.
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