Sinatra 是多线程的吗? [英] Is Sinatra multi threaded?

查看:56
本文介绍了Sinatra 是多线程的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Sinatra 是多线程的吗?我在其他地方读到默认情况下 sinatra 是多线程的",这意味着什么?

Is Sinatra multi-threaded? I read else where that "sinatra is multi-threaded by default", what does that imply?

考虑这个例子

get "/multithread" do
  t1 = Thread.new{
    puts "sleeping for 10 sec"
    sleep 10
    # Actually make a call to Third party API using HTTP NET or whatever.
  }
  t1.join
  "multi thread"
end

get "/dummy" do
  "dummy"
end

如果我随后在另一个选项卡或浏览器中访问/multithread"和/dummy",则在/multithread"请求完成之前,无法提供任何服务(在这种情况下为 10 秒).万一活动冻结,应用程序变得无响应.

If I access "/multithread" and "/dummy" subsequently in another tab or browser then nothing can be served(in this case for 10 seconds) till "/multithread" request is completed. In case activity freezes application becomes unresponsive.

我们如何在不生成应用程序的另一个实例的情况下解决这个问题?

How can we work around this without spawning another instance of the application?

推荐答案

tl;dr Sinatra 与 Threads 配合良好,但您可能需要使用不同的 Web 服务器.

Sinatra 本身没有强加任何并发模型,它甚至不处理并发.这是由 Rack 处理程序(Web 服务器)完成的,例如 Thin、WEBrick 或Passenger.Sinatra 本身是线程安全的,这意味着如果您的 Rack 处理程序使用多个线程来处理请求,它就可以正常工作.但是,由于 Ruby 1.8 仅支持绿色线程,而 Ruby 1.9 具有全局 VM 锁,线程并没有被广泛用于并发,因为在两个版本中,线程不会真正并行运行.然而,这将是关于 JRuby 或即将推出的 Rubinius 2.0(两个替代的 Ruby 实现).

Sinatra itself does not impose any concurrency model, it does not even handle concurrency. This is done by the Rack handler (web server), like Thin, WEBrick or Passenger. Sinatra itself is thread-safe, meaning that if your Rack handler uses multiple threads to server requests, it works just fine. However, since Ruby 1.8 only supports green threads and Ruby 1.9 has a global VM lock, threads are not that widely used for concurrency, since on both versions, Threads will not run truly in parallel. The will, however, on JRuby or the upcoming Rubinius 2.0 (both alternative Ruby implementations).

大多数使用线程的现有 Rack 处理程序将使用线程池来重用线程,而不是为每个传入的请求实际创建一个线程,因为创建线程不是免费的,尤其是.在 1.9 上,线程以 1:1 的比例映射到本地线程.绿色线程的开销要小得多,这就是为什么光纤(如上述 sinatra-synchrony 使用的基本上是协作调度的绿色线程)最近变得如此流行.您应该知道任何网络通信都必须通过 EventMachine,因此您不能使用 mysql gem,例如,与您的数据库对话.

Most existing Rack handlers that use threads will use a thread pool in order to reuse threads instead of actually creating a thread for each incoming request, since thread creation is not for free, esp. on 1.9 where threads map 1:1 to native threads. Green threads have far less overhead, which is why fibers, which are basically cooperatively scheduled green threads, as used by the above mentioned sinatra-synchrony, became so popular recently. You should be aware that any network communication will have to go through EventMachine, so you cannot use the mysql gem, for instance, to talk to your database.

对于网络密集型处理,光纤可以很好地扩展,但对于繁重的计算却惨败.如果您使用纤程,您不太可能遇到竞争条件,这是并发的常见陷阱,因为它们只在明确定义的点(同步,每当您等待 IO 时)进行上下文切换.还有第三种常见的并发模型:进程.您可以使用预分叉服务器或自己启动多个进程.虽然乍一看这似乎是个坏主意,但它有一些优点:在普通的 Ruby 实现中,这是同时使用所有 CPU 的唯一方法.并且您避免共享状态,因此根据定义没有竞争条件.此外,多进程应用程序可以在多台机器上轻松扩展.请记住,您可以将多个进程与其他并发模型(事件、合作、抢占)结合起来.

Fibers scale well for network intense processing, but fail miserably for heavy computations. You are less likely to run into race conditions, a common pitfall with concurrency, if you use fibers, as they only do a context switch at clearly defined points (with synchony, whenever you wait for IO). There is a third common concurrency model: Processes. You can use preforking server or fire up multiple processes yourself. While this seems a bad idea at first glance, it has some advantages: On the normal Ruby implementation, this is the only way to use all your CPUs simultaniously. And you avoid shared state, so no race conditions by definition. Also, multiprocess apps scale easily over multiple machines. Keep in mind that you can combine multiple process with other concurrency models (evented, cooperative, preemptive).

选择主要由你使用的服务器和中间件决定:

The choice is mainly made by the server and middleware you use:

  • 多进程、非预分叉:Mongrel、Thin、WEBrick、Zbatery
  • 多进程、预分叉:Unicorn、Rainbows、Passenger
  • Evented(适合 sinatra 同步):Thin、Rainbows、Zbatery
  • 线程:Net::HTTP::Server、Threaded Mongrel、Puma、Rainbows、Zbatery、Thin[1]、Phusion 乘客企业 >= 4

[1] 自 Sinatra 1.3.0 起,Thin 将以线程模式启动,如果它由 Sinatra 启动(即使用 ruby app.rb,但不使用 thin 命令,也不能使用 rackup).

[1] since Sinatra 1.3.0, Thin will be started in threaded mode, if it is started by Sinatra (i.e. with ruby app.rb, but not with the thin command, nor with rackup).

这篇关于Sinatra 是多线程的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆