sys.getswitchinterval()在PyQt中的工作原理及线程响应相关问题咨询
先给大家铺垫下Python里的线程切换机制:
从Python官方文档里关于sys.setswitchinterval()的说明:
Set the interpreter’s thread switch interval (in seconds). This floating-point value determines the ideal duration of the “timeslices” allocated to concurrently running Python threads. Please note that the actual value can be higher, especially if long-running internal functions or methods are used. Also, which thread becomes scheduled at the end of the interval is the operating system’s decision. The interpreter doesn’t have its own scheduler.
配套的getswitchinterval()用来获取当前切换间隔值,默认是0.005秒。
这个机制从Python 3.2(2009年)就存在了,初衷是解决CPU密集型线程霸占GIL的问题——之前的Python版本里,CPU-bound线程会一直持有GIL,其他线程根本抢不到运行机会。后来Antoine Pitrou在Python3.2里修复了这个问题:
This problem was fixed in Python 3.2 in 2009 by Antoine Pitrou who added a mechanism of looking at the number of GIL acquisition requests by other threads that got dropped and not allowing the current thread to reacquire GIL before other threads got a chance to run.
最早这个功能叫sys.setcheckinterval()/sys.getcheckinterval(),现在已经废弃了,当时是用机器指令数而不是时间间隔来控制线程切换时机的。
不过我在使用PyQt5的时候遇到了一个疑问:当我用QThread实现一个计算密集型的工作线程时,如果不在工作线程里加time.sleep(...)调用,GUI事件线程就会被完全冻结,必须加sleep才能让GUI保持响应。
按照上面说的Python3.2+的切换间隔机制,不是应该自动让工作线程定期让出GIL,给GUI线程运行的机会吗?为什么这个机制在PyQt里好像不起作用?
我猜会不会是PyQt自己实现了一套线程调度架构,覆盖了Python的默认机制?但如果是这样的话,为什么简单的time.sleep(..)就能解决GUI响应的问题呢?显然sleep和Python的切换间隔机制做的不是一回事,有没有大佬能解释下在PyQt场景里,这两者到底有什么不同?
(注:我用的是PyQt5,应该和后续PyQt版本情况类似)
备注:内容来源于stack exchange,提问作者mike rodent

