python 和 ruby 都有 GIL,但是好像一些其他语言没有 GIL,请问其他语言(比如 java)如何处理这个问题的?是所有库都有 lock 保证资源安全吗?
不是 python, ruby 有 GIL,而是 python 的最流行的解释器 cpython 和 ruby 的最流行的解释器 mri 都实施了 GIL .
解释器中实施 GIL 与否是个设计决定,选任何一个都要做出些妥协,具体可以搜搜看。
JVM 没有 GIL,但是也有锁,只是锁的粒度细小得多,一般不会整个线程给你锁上。
jvm 的锁优化做的远胜 ruby,python,种类多,偏向缩,可重入锁,7 里面的并发库加入以 cas(compare and swap)实现的解决锁开销问题也是一大亮点,也是为了适应多核环境,ruby python 主流解释器无法完全开发多核性能。相应的,设计复杂度上就高出几个数量级。
以我阅读《Seven Concurrency Models in Seven Weeks》第一章了解到的,Java 线程需要程序员处理的问题一样有,然后作者再三强调用锁很容易出错,推荐用其它并发/平行模型。
GIL 是个伪命题 ——初级程序员很容易被 80 年代的中文翻译过来的垃圾过时教程说,解决 concurrency 只能用多线程。然后就拿着多线程这个锤子到处找钉子。
其实这里要区分一个 IO 密集和 CPU 密集的,IO 密集,即便有 GIL 也可以通过 coroutine 或者 Fiber 很好解决,性能不低。
CPU 密集——这个得好好想一下。
所以 GIL 不是不能用多线程问题,而是多线程只能用单个核心的问题。但是实际上,大家也不是没见过 Chrome 啊,3D 游戏里只把一个核心占满的情况。这不就是只能利用一个核心的毛病么?为啥 GIL 就臭名昭著,而 C/C++ 大家就会很自然想到一个借口说你代码写得不好呢?
但是反过来说,你要用脚本语言解决计算密集问题?你 TM 逗我?计算性能问题,首先就得说 MRI/CPython 这个和 C 语言 30 倍性能差距的问题。。。。。。。。。。
就算没 GIL 的 Java 里,写多线程也不是个什么好体验。JVM 是不会卡进程,各种锁得你自己搞。搞得不好还是会卡进程。就算 C/C++ 直接用 pthreads,写起来是各种坑。
在实际应用中,GIL 给大家带来的不便是 0。绝大多数市面上能看到的多线程教程,无论什么语言,都是用来解决 io wait 的问题的。io wait 在 Ruby/Python 已经有 n 种解决方案了。
你如果写代码真碰到 GIL 问题了,请一定怀疑你的姿势不对。
自后还是要喷一下:为什么 nodejs 没有 GIL 问题?因为别人压根不支持多线程。(还不是活得好好的。)