困惑,像python,ruby单线程的语言?不像说java?(适用于网络应用)

Bla*_*man 41 ruby python java multithreading

我正在阅读Clojure是如何"酷"的,因为它的语法+它在JVM上运行,所以它是多线程等等.

那么像ruby和python这样的语言是单线程吗?(作为Web应用程序运行时).

python/ruby​​和在tomcat上运行java之间有什么根本区别?

在所有情况下,Web服务器都没有可以使用的线程池吗?

Jör*_*tag 42

Python和Ruby都完全支持多线程.有些实现(例如CPython,MRI,YARV)实际上并不能并行运行线程,但这是对这些特定实现的限制,而不是语言.这类似于Java,其中也有一些实现不能并行运行线程,但这并不意味着Java是单线程的.

请注意,在这两种情况下都有许多可以并行运行线程的实现:PyPy,IronPython,Jython,IronRuby和JRuby只是其中的几个例子.

Clojure与Python,Ruby,Java,C#,C++,C,PHP以及几乎所有其他主流和非主流语言之间的主要区别在于Clojure拥有一个理智的并发模型.所有其他语言都使用线程,我们已知这些线程是一个糟糕的并发模型至少40年.Clojure OTOH有一个理智的更新模型,它不仅可以向程序员提供一个但实际上多个理智的并发模型:原子更新,软件事务内存,异步代理,并发感知线程局部全局变量,期货,承诺,数据流并发在未来甚至可能更多.

  • 从技术上讲,股票实施"是多线程的".但由于Global Interpreter Lock,一次只能执行一个线程.所以从本质上讲......不,它们不是多线程的.这适用于Ruby和Python. (9认同)
  • 说CPython不能并行运行线程有点夸大 - 线程并发运行但不能使用多个处理器,除了在定义的位置(比如等待文件或套接字上的I/O,或者使用某些C库时)例如,lxml允许在解析时并行执行).多处理器的性能损失仅影响少数情况. (5认同)
  • Ruby 1.8版有两个主要实现:MRI和JRuby。到目前为止,YARV是最常见的1.9。因此可以肯定地说,MRI / YARV是默认设置。根据默认定义,考虑了最流行和广泛使用的实现。这对于使用红宝石的任何人来说可能都是很清楚的,所以我认为没有理由选择措辞。只是我的2美分。 (2认同)
  • 用律师的笑话来解释一下,95%的用户使用的红宝石(YARV / MRI)的使用使该语言名不副实! (2认同)

Gle*_*ard 12

一个混乱的问题,有很多困惑的答案......

首先,线程和并发执行是不同的事情.Python支持线程很好; 它不支持任何实际实现中的并发执行.(在所有严肃的实现中,一次只能执行一个VM线程;许多尝试解耦VM线程都失败了.)

其次,这与网络应用程序无关.您不需要Python后端在同一进程中并发执行.您为每个后端生成单独的进程,然后每个进程可以并行处理请求,因为它们根本没有捆绑在一起.

使用线程进行Web后端是一个坏主意.为什么将线程 - 锁定,竞争条件,死锁 - 带来的危险本身就是令人尴尬的并行?将每个后端塞进自己独立的过程中更加安全,避免了所有这些问题的可能性.

(共享内存空间有一些优点 - 通过共享静态代码可以节省内存 - 但是无需线程即可解决.)


Jam*_*hek 10

CPython有一个Global Interpreter Lock,它可以降低Python中多线程代码的性能.在某些情况下,净效应是由于锁定争用,线程实际上不能同时运行.并非所有Python实现都使用GIL,因此这可能不适用于JPython,IronPython或其他实现.

语言本身确实支持线程和其他异步操作.python库也可以在内部支持线程,而不直接将它暴露给Python解释器.

如果您听说过有关Python和线程的任何负面消息(或者它不支持它),那么可能是某些人遇到GIL导致瓶颈的情况.


Bal*_*usC 6

当然,网络服务器将拥有一个线程池.这只是在你的程序控制范围之外.这些线程用于处理HTTP请求.每个HTTP请求都在一个单独的线程中处理,当关联的HTTP响应完成后,线程将被释放回池中.如果网络服务器没有这样的池,那么它的服务速度会非常慢.

编程语言是单线程还是多线程取决于使用相关语言以编程方式生成线程的可能性.如果那是不可能的,那么语言是单线程的,例如PHP.据我所知,Ruby和Python都支持多线程.


Ben*_*hes 5

简短的答案是,它们是单线程的。

长答案是取决于。

JRuby是多线程的,可以像其他Java代码一样在tomcat中运行。MRI(默认红宝石)和Python都具有GIL(全局解释器锁),因此是单线程的。

Web服务器的工作方式因可用服务器配置的数量而更加复杂。对于大多数ruby应用程序,至少有两级服务器,一个代理/静态文件服务器(如nginx),然后是ruby应用程序服务器。

Nginx不使用apache或tomcat之类的线程,它使用非阻塞事件(我认为是派生的工作进程)。与本地线程的开销和调度效率低下相比,这允许它处理更高级别的并发。

各种ruby应用程序服务器还以不同的方式工作,以在没有线程的情况下获得高吞吐量和并发性。Thin使用libev和Nginx之类的异步事件模型。Mongrel使用工作进程的循环池。Unicorn使用本机Unix IPC(在套接字上选择)通过一个主代理套接字将平衡负载分叉到一组进程中。

线程只是解决并发的一种方法。多个进程和事件模型是与Unix基础紧密相关的另一种方法。这从根本上不同于Java对待世界的方式。


Mar*_*_io 5

Python

让我尝试用更简单的方式来表达,而不是更详细的答案。

这里答案的核心实际上与 Python 是单线程还是多线程无关。与多处理相比,它更多地与线程有关。

说 Python 是“单线程”并不能真正反映现实,因为在一个 Python 进程中肯定可以运行多个线程。只需使用线程库,并创建多个线程即可。至此,您刚刚证明了 Python 不是单线程的。

但在 Python 中使用多线程并不意味着您同时使用多个 CPU 处理器。事实上,全局解释器锁可以防止这种情况发生。所以这就是问题出现的地方。

基本上,Python 中的线程不能用于并行 CPU 计算。但是您可以通过使用多处理而不是多线程来使用 Python 进行并行 CPU 计算。

我发现这篇文章在研究这个问题时非常有帮助:https://timber.io/blog/multiprocessing-vs-multithreading-in-python-what-you-need-to-know/。它包括您何时想要使用多处理与多线程的真实示例。