У меня есть многопоточная программа, и недавно я столкнулся с интересным явлением.
Если я вызову метод print
в рабочем потоке, программа станет очень реактивной. Там нет большой хитрости, просто вызов метода print
решает все.
Я недавно прочитал статью о глобальной блокировке интерпретатора Python, также известной как GIL, и в ней говорилось, что GIL выпускается после выполнения операций ввода-вывода. Как вы думаете, print
вызов также связан с вводом / выводом?
Мне бы очень хотелось, чтобы моя программа реагировала, но, очевидно, неудобно выводить данные на стандартный вывод во время работы. Поэтому я попытался перенаправить вывод на /dev/null
, но это не решило проблему:
with contextlib.redirect_stdout(None):
print('')
Буду признателен, если у вас есть идея, чтобы я мог воспроизвести тот же эффект с помощью следующего вызова, но без вывода чего-либо:
print('')
Насколько я вижу, GIL высвобождается, пока переводчик работает для print('')
. Может быть, мне нужен такой короткий перерыв, который освободит меня от GIL.
Это только для вашего сведения, но я попытался вызвать следующий метод:
print('', end='', flush=True)
Конечно, он ничего не выгружал, но моя программа стала немного неровной, и казалось, что поток занимал время выполнения, поэтому другие потоки работали очень редко.
Обновление
Если я позвоню usleep(1)
из QThread, ожидая, что он будет спать 1 нас, тогда он ждет намного больше, чем я указал. Например. рабочий поток запускается каждые 1 мс, что очень медленно, потому что я ожидал запустить его в микросекундном порядке. Вызов print('')
заставляет поток работать в порядке нескольких микросекунд. В этом смысле я называю это реактивным.
Обновление
Я чувствую, что что-то влияет на время выполнения потока, но это не usleep
или time.sleep()
. Тем не менее, я столкнулся с фактом, что print
может отбросить блокиратор. Поэтому я хотел бы знать, что на самом деле выбивает блокиратор.