Подтвердить что ты не робот

Что делает sys.exit действительно с несколькими потоками?

Я действительно был смущен sys.exit() в python. В документации python, говорится: "Выход из Python"; означает ли это, когда sys.exit() вызывается в программе python, процесс будет завершен? Если это так, приведенный ниже код показывает другой результат:

import sys
import time
import threading

def threadrun():
    while(True):
        time.sleep(1)

if __name__=="__main__":
    t=threading.Thread(target=threadrun)
    t.start()
    sys.exit()

Запуск этой программы в Linux, результат не был ожидаемым, поскольку документация на python говорит, но все еще работает в системе, так что действительно делает sys.exit()?

4b9b3361

Ответ 1

В соответствии с документацией sys.exit() повышает SystemExit:

Выйдите из интерпретатора, подняв SystemExit (статус).

Если SystemExit достигает обработчика исключений по умолчанию, он вызывает handle_system_exit(), который более или менее продвигается к Py_Finalize(), который, в свою очередь, вызывает wait_for_thread_shutdown() в Python 2, поэтому sys.exit() совпадает с нормальным, падающим снизу основного модуля, в ожидании завершения всех потоков не-демона.

Ответ 2

(Перефразируя то, что в документации по Python 2 для потоковых объектов)

Обычно программа на Python завершается только тогда, когда нет ничего, кроме демона темы (игнорируя себя) остались запущенными. Объект 'main thread', который соответствует начальному потоку управления в программе, не является потоком демона. Потоки, созданные с помощью threading.Thread, наследуют свой демонический статус от создаваемого потока, поэтому, если это основной поток, они также будут не демоническими.

Это означает, что по умолчанию любые потоки, созданные и запущенные вашей основной программой, не позволят ей завершиться, если они все еще работают, когда основной поток завершается (с помощью sys.exit() или просто путем нажатия на конец его кода). Другими словами, программа завершается только в том случае, если не осталось живых потоков, не являющихся демонами (другими словами, только демоны).

Вы можете переопределить это поведение по умолчанию, явно установив ✶✶ daemon свойство любого создал объекты потока в True перед его запуском.

if __name__=="__main__":
    t = threading.Thread(target=threadrun)
    t.daemon = True  # Explicitly set property.
    t.start()
    sys.exit()

Что позволит программе фактически завершиться при вызове sys.exit() (хотя вызывать его явно так не нужно, так как он все равно находится в конце скрипта).


Поток демона - это поток с низким приоритетом, который работает в фоновом режиме и не препятствует выходу интерпретатора. См. Описание потоков демонов.

✶✶ В Python 3.3 был добавлен аргумент ключевого слова daemon к Thread конструктор класса, Это означает, что, начиная с этой версии, вы можете просто использовать:

    # Sets whether the thread is daemonic via "daemon" keyword argument.
    t = threading.Thread(target=threadrun, daemon=True)

Тем не менее, делая это отдельно с помощью явного оператора присвоения атрибута все еще работает, и поэтому будет более переносимым способом Делать это.

Ответ 3

В вашем случае конец программы - это когда последний поток будет прерван. Возможно, что-то вроде метода join() (как в Java) в python будет ожидать других потоков.

Пожалуйста, прочитайте эту статью (есть хорошее объяснение, как играть с потоками в вашем случае Использование потоков. Thread.join()

и

документация https://docs.python.org/2/library/threading.html (но расслабьтесь, это только для дополнительных знаний.

и прочитайте эту статью о свойстве демона (если вы не хотите ждать, пока другие потоки не прекратятся Значение свойства демона в потоках Python