设计复杂度啊,大哥,两个都要那就两个都性能底,还开关,想太多了,而且 Python 强大的 C 扩展,谁给你兼容,多线程编程本来就复杂,重新设计解释器干掉 gil 不是啥难事,但是要在通用场景下取得更好性能以及对现有模块和 C 扩展有良好兼容可就难了,而且以 Python 的主要使用场景来看,干不干掉 GIL 其实意义不大,反正 Python 做出的牛逼的东西像 tensorflow 都是 C 或者 C++扩展的本来就不受 GIL 限制,否则有 ironpython 和 jython 你看如何
至于那些已经存在的 C 扩展,虽然我也不太懂 C 扩展,但我猜如果本来就隐式或显式依赖 GIL ,那么似乎本来就不适合多线程并行? 而且“多线程细粒度 GIL”是可选的,如果不兼容那么回退到原来的粗粒度 GIL 就是了。
虽然我也不知道去掉 GIL 有什么意义,不过也许有利于并行计算?
至于 python 其他没有 GIL 的实现,老实说我没用过,而且看上去版本更新缓慢……
ysc3839
2021-10-24 06:11:10 +08:00
那为什么不做成编译时的开关呢?
O5oz6z3
2021-10-24 06:15:57 +08:00
@msg7086 #2 我的意思就是,如果暂时不考虑成本,这个方案理论上可行吗? 况且细粒度 GIL 似乎(很久)以前有人实现过,参考上面 #3 的链接。
至于你所说的“运行时判断”,如果我没理解错的话,是指每次解释执行字节码指令的时候,判断使用哪种 GIL ?我不是这个意思,我是指上面提到的根据命令行开关(例如`python --threads ...`)调用对应的“入口函数”(`Py_Initialize`/`Py_Initialize_threads`)。
C 扩展这点也参考上面 #3 。虽然 CPU 密集确实应该用 C 扩展来解决,但 C 扩展的缺点是,需要编译(和需要写 C 语言……)。
我说一个观点,就是在 CPython 漫长的发展过程中 Extension 的接口会发生抽象泄漏,从而制约其底层实现的改变。具体可以看 Hyrum's Law https://www.hyrumslaw.com/
展开来说,一个有很多用户使用的接口,无论其抽象做的多好,用户的使用最终多少会透过这层接口而去依赖背后的具体实现。CPython Extension API 虽然没有暴露太多和 GIL 相关的 API ,但你很难说不存在某些扩展,其正确性依赖于「解释器里有个全局锁」这一事实。就算细粒度锁或去除 GIL 的性能和安全问题解决了,CPython 作为正统及使用最广泛的版本也不会贸然采用。这其中会有很长的验证过程。