- A+
修复PyGILState_Ensure()
2年的时间里,我完全不记得这个bug了。 2016年3月,我修改了Steve的测试程序,使其与Linux兼容(该测试是为Windows编写的)。 我成功地重现了我电脑上的错误,并且为PyGILState_Ensure()写了一个修复程序。
于是我关闭了问题bpo-20891 ...
macOS上测试发生随机崩溃
一切都很好......但一周后,我注意到我新增加的单元测试在macOS buildbots上发生了随机崩溃。 我成功地手动重现了这个bug,第三次运行时崩溃的例子:
我发现有一个修复是管用的:在PyThread_start_new_thread()中调用PyEval_InitThreads()。 那么,一旦生成第二个线程就会创建GIL锁。 当两个线程正在运行时,GIL不能再创建。 至少,用python代码不可以建。 如果一个线程不是由Python产生的话,此修复不能解决这个问题,但是这个线程调用了PyGILState_Ensure()。
提出Py_Initialize()的第二个修复
我提出了Py_Initialize()的第二个修复,以便在Python启动时始终创建GIL,并且不再“按需”,以防止出现竞态条件的风险:
Nick Coghlan问我是否可以通过性能基准测试我的补丁。 我在我的PR 4700上运行pyperformance。差异至少5%:
哦,5个基准比较慢。 Python中性能退步是不受欢迎的:我们正在努力让Python变得更快!
运行新的基准测试,和应用于master的第二个修复
在2018年1月底,我再次运行了那5个由于我的PR(Pull request)而变慢的基准测试。 我使用了CPU隔离,在我的笔记本电脑上手动运行这些基准测试:
好吧,它证实了,依照Python性能基准套件,我的第二个修复对性能没有显著的影响。
我决定将我的修复程序推送到master分支,提交2914bb32:
然后我在master分支上重新启用了test_embed.test_bpo20891()。
是不是异常恐怖呢?一个bug居然花了四年才解决!