印刷方法与GIL

2024-04-19 07:36:46 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个多线程程序,最近遇到了一个有趣的现象。你知道吗

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

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

我真的很想让我的程序反应,但它显然是尴尬的转储数据上的标准输出,而它的运行。所以我尝试将输出重定向到/dev/null,但没有解决问题:

with contextlib.redirect_stdout(None):
    print('')

如果您有这样一个想法,我可以复制与以下通话相同的效果,但不转储任何内容,我将不胜感激:

print('')

在我看来,GIL是在解释器为print('')工作时释放的。也许我需要这样一个短暂的休息,让我从GIL中解脱出来。你知道吗

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

print('', end='', flush=True)

当然,它没有转储任何东西,但是我的程序变得有点不稳定,看起来线程占用了执行时间,所以其他线程很少运行。你知道吗

更新

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

更新

我觉得线程的执行时间有问题,但不是usleeptime.sleep()。然而,我面临一个事实print可以将阻塞器踢走。所以我想知道什么是真正踢出阻滞剂。你知道吗


Tags: 方法程序技巧顺序文章时间全局线程
1条回答
网友
1楼 · 发布于 2024-04-19 07:36:46

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

第二,对于usleep,这个函数可以保证睡眠至少你所要求的微秒,但是它不会睡眠少于操作系统调度程序的持续时间。在Linux上,这通常是在1000hz、250hz或100hz下运行的,但是可能会有很大的变化。你知道吗

现在,如果您想要比这更细粒度的东西,有^{}调用,它将“忙等待”小于2ms的延迟,而不是调用内核。你知道吗

相关问题 更多 >