Будет ли Python поток демона заблокирован занятым родительским потоком, если есть GIL? - PullRequest
0 голосов
/ 18 февраля 2020

Я знаю, Python поток демона будет автоматически выходить, если выход родительского потока. Причина, по которой я спрашиваю «да», потому что мой основной поток иногда работает над интенсивным вычислением ЦП, которое блокирует сообщение об ударе сердца. Другой модуль думает, что эта услуга мертва и планирует похороны.

Я хочу использовать какой-нибудь поток демона (или процесс?), Который является дочерним по отношению к основному потоку, для отправки сообщения сердцебиения.

Мой вопрос заключается в том, блокирует ли мой основной поток, например:

while True:
   a = a + 1

Будет ли также заблокирован мой дочерний поток демона? любой пример или доказательство? Какую роль здесь играет GIL (Global Interpreter Lock)?

Редактировать

К точке @ ShadowRanger, как показано в следующем примере, официант может выйти из сообщения, учитывая, что рабочий поток блокируется (занимая 220% ресурсов ЦП)

import time
from threading import Thread

class worker(Thread):
    def run(self):
        t = 10
        x = 10
        while True:
            x = t + 1

class waiter(Thread):
    def run(self):
        for x in xrange(100,150):
            print x
            time.sleep(0.5)

def run():
    worker().start()
    waiter().start()

run()

Ответы [ 3 ]

2 голосов
/ 18 февраля 2020

Если ваш основной поток выполняет Python байт-код (не встроенный в дорогостоящий долгосрочный вызов модуля расширения C, который содержит GIL для длины вызова и не возвращает интерпретатору для долгое время), тогда поток демона в конечном итоге получит возможность запуска; через некоторое время основной поток будет прерван (за считанные миллисекунды), и поток демона будет работать, пока основной поток заблокирован. До тех пор, пока ваш интервал пульса измеряется в секундах, с этим все должно быть в порядке.

В каждый момент времени выполняется только один поток, но оба будут чередовать выполнение.

Сценарий с длительным GIL чтобы быть ясным, удержание за удлинитель может произойти случайно; все расширения по умолчанию содержат GIL. В то время как популярные, широко используемые расширения, такие как numpy, стараются выпускать GIL, когда у них достаточно работы, расширения, написанные менее опытными разработчиками (особенно теми, которые пишут на Cython без знания GIL), с большей вероятностью удерживайте GIL в течение длительного времени, поэтому, если ваше сердцебиение не не работает, а модули расширения задействованы, они, вероятно, являются виновником. Простой while True: a = a + 1 l oop был бы безопасен (при условии, что a не какой-то странный тип расширения); GIL может быть легко переключен там.

1 голос
/ 18 февраля 2020

По соображениям безопасности я бы go с multiprocessing здесь. Ваш ответ сердцебиения может быть отдельным процессом, освобожденным от цепей GIL. В противном случае вы будете зависеть от неопределенного потока кода c и можете получить случайные ошибки в наименьшие ожидаемые моменты.

0 голосов
/ 18 февраля 2020

Вероятно, обратный вызов IO l oop внутри потока блокирует сердцебиение. Как указывает @ShadowRanger, поток чередуется, что не должно блокировать периодический обратный вызов другого потока (кроме проблемного расширения c python). В моем случае, вероятно, виновником является очередь обратного вызова iol oop внутри потока. Нет чередования в очереди вызовов iol oop.

...