困惑,像Python、Ruby这样的语言是单线程的吗?与Java不同?(用于Web应用)
我在看关于Clojure的讨论,大家说它很“酷”,因为它的语法很特别,而且它可以在JVM上运行,所以支持多线程等等。
那像Ruby和Python这样的语言在运行网络应用的时候,是不是本质上都是单线程的呢?
Python和Ruby跟Java在Tomcat上运行有什么根本的区别呢?
难道不管是什么网络服务器,都会有一池线程可以使用吗?
13 个回答
CPython有一个叫做全局解释器锁的东西,这个锁会影响Python中多线程代码的性能。简单来说,有时候因为这个锁的存在,线程不能同时运行,因为它们在争抢这个锁。并不是所有的Python版本都有这个锁,所以像JPython、IronPython等其他版本可能就不受这个影响。
不过,Python语言本身是支持多线程和其他异步操作的。Python的库也可以在内部支持多线程,但不一定会直接让你在Python解释器中看到。
如果你听说过关于Python和多线程的负面评价(或者说它不支持多线程),那很可能是因为有人遇到了全局解释器锁导致的性能瓶颈。
这个问题让人困惑,回答也各有各的说法……
首先,线程和并发执行是两回事。Python的线程支持得很好,但在实际应用中,它并不支持真正的并发执行。(在所有严肃的实现中,只有一个虚拟机线程可以同时执行;很多尝试让虚拟机线程解耦的努力都失败了。)
其次,这对网页应用来说并不重要。你不需要让Python后端在同一个进程中同时执行。你可以为每个后端启动独立的进程,这样每个进程就可以并行处理请求,因为它们之间没有任何联系。
在网页后端使用线程并不是个好主意。为什么要把线程带来的麻烦——比如锁定、竞争条件和死锁——引入到本来就可以轻松并行处理的事情中呢?把每个后端放在自己的独立进程中要安全得多,这样就能避免这些潜在的问题。
(共享内存空间是有好处的——可以节省内存,因为可以共享静态代码——但这可以在不使用线程的情况下解决。)
Python和Ruby都支持多线程。虽然有些具体的实现(比如CPython、MRI、YARV)实际上不能同时运行多个线程,但这只是这些实现的限制,并不是语言本身的问题。这和Java类似,Java也有一些实现不能并行运行线程,但这并不意味着Java只能单线程。
需要注意的是,在这两种情况下,有很多实现是可以并行运行线程的,比如PyPy、IronPython、Jython、IronRuby和JRuby等,这些只是其中的一些例子。
Clojure和Python、Ruby、Java、C#、C++、C、PHP以及几乎所有其他主流和非主流语言之间的主要区别在于,Clojure有一个“合理”的并发模型。其他语言使用线程,而我们知道这种线程模型在过去40年里一直被认为是不太好的选择。相比之下,Clojure有一个合理的更新模型,这让它不仅能提供一种,而是多种合理的并发模型给程序员使用:原子更新、软件事务内存、异步代理、并发感知的线程局部全局变量、未来值、承诺、数据流并发,未来可能还会有更多。