Python 印刷方法与GIL

Python 印刷方法与GIL,python,multithreading,gil,Python,Multithreading,Gil,我有一个多线程程序,最近遇到了一个有趣的现象 如果我在线程的辅助线程中调用print方法,程序会变得非常被动。没有什么大技巧,只要调用print方法就可以解决所有问题 我最近读了一篇关于Python的全局解释器锁(也称为GIL)的文章,它说一旦执行了I/O绑定的东西,就会释放GIL。您认为print调用也是I/O绑定吗 我真的很想让我的程序成为被动的,但是当它运行时,在stdout上转储数据显然是很尴尬的。因此,我尝试将输出重定向到/dev/null,但没有解决问题: with contextl

我有一个多线程程序,最近遇到了一个有趣的现象

如果我在线程的辅助线程中调用
print
方法,程序会变得非常被动。没有什么大技巧,只要调用
print
方法就可以解决所有问题

我最近读了一篇关于Python的全局解释器锁(也称为GIL)的文章,它说一旦执行了I/O绑定的东西,就会释放GIL。您认为
print
调用也是I/O绑定吗

我真的很想让我的程序成为被动的,但是当它运行时,在stdout上转储数据显然是很尴尬的。因此,我尝试将输出重定向到
/dev/null
,但没有解决问题:

with contextlib.redirect_stdout(None):
    print('')
如果您有什么想法,我可以在不放弃任何内容的情况下,通过以下通话再现相同的效果,我将不胜感激:

print('')
就我所见,当解释器为
print(“”)
工作时,GIL被释放。也许我需要这样一个短暂的休息,让我从GIL中解脱出来

这只是供您参考,但我已尝试调用以下方法:

print('', end='', flush=True)
当然,它没有转储任何内容,但是我的程序变得有点混乱,看起来线程占用了执行时间,所以其他线程很少运行

更新

如果我调用QThread的
usleep(1)
,希望让它休眠1us,那么它等待的时间比我指定的要长得多。例如线程工作程序每1毫秒运行一次,速度非常慢,因为我希望以微秒级运行它。调用
print(“”)
使线程以几微秒的顺序运行。在这个意义上,我称之为反应性

更新


我觉得有什么东西在影响线程的执行时间,但不是
usleep
time.sleep()
。然而,我遇到了一个事实,
print
可以将拦截器踢走。所以我想知道到底是什么在赶走阻挡者。

这里发生了两件事。首先,对于GIL本身,大多数I/O函数将在调用平台代码之前释放它,因此
print
调用肯定会释放它。这自然会让运行时安排另一个线程

其次,对于
usleep
,此函数保证睡眠时间至少与您要求的微秒数相同,但睡眠时间不会少于操作系统调度程序的持续时间。在Linux上,这通常以1000 Hz、250 Hz或100 Hz的频率运行,但变化很大


现在,如果您想要更细粒度的东西,那么有一个调用将“忙碌等待”小于2毫秒的延迟,而不是调用内核。

print
是一个相对较慢的函数,因此它可能会更改使用它的函数的计时。小心,因为添加了
print
功能,您可能幸运地隐藏了竞争条件。谢谢您的评论!我理解你的建议,但我不坚持印刷法。我只需要一个方法,使线程快速。最初我试图调用PyQt的QThread类的
uleep(1)
,但它似乎比我指定的睡眠时间长得多。因此,我删除了
usleep
,并意识到只要调用
print(“”)
,线程就会变得非常被动。你说的被动是什么意思?如果我调用QThread的
usleep(1)
,希望让它睡眠1us,那么它等待的时间比我指定的要长得多。例如线程工作程序每1毫秒运行一次,速度非常慢,因为我希望以微秒级运行它。调用
print(“”)
使线程以几微秒的顺序运行。从这个意义上说,我称之为反应性。我感觉有什么东西在麻醉线程的执行时间,但它不是
usleep
time.sleep()
。然而,我遇到了一个事实,
print
可以将拦截器踢走。所以我想知道到底是什么在赶走阻挡者。谢谢你的提示!我想我可以试着得到这些信息。一旦我确认了结果,我会接受你的回答。再次感谢你!