Sinatra是多线程的吗?

ch4*_*d4n 45 ruby sinatra

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

考虑这个例子

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
Run Code Online (Sandbox Code Playgroud)

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

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

Kon*_*ase 91

tl; Sinatra博士与Threads配合得很好,但你可能不得不使用不同的Web服务器.

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

大多数使用线程的现有Rack处理程序将使用线程池来重用线程,而不是为每个传入请求实际创建一个线程,因为线程创建不是免费的,尤其是.在1.9上,线程将1:1映射到本机线程.绿色螺纹的开销要小得多,这就是为什么纤维,基本上是合作安排的绿色螺纹,如上面提到的sinatra-synchrony所使用的,最近变得如此受欢迎.您应该知道任何网络通信都必须通过EventMachine,因此您不能使用mysqlgem来与您的数据库通信.

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

选择主要取决于您使用的服务器和中间件:

  • 多进程,非预先执行:Mongrel,Thin,WEBrick,Zbatery
  • 多进程,预制:独角兽,彩虹,乘客
  • Evented(适合sinatra-synchrony):Thin,Rainbows,Zbatery
  • 螺纹:Net :: HTTP :: Server,螺纹杂种,Puma,彩虹,Zbatery,薄[1],Phusion Passenger Enterprise> = 4

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


asa*_*aki 6

在谷歌上搜索,发现这个宝石:

西纳特拉同步性

这对你有帮助,因为它会触动你的问题.

还有一个基准测试,他们做的几乎和你想要的一样(外部电话).

结论:EventMachine就是这里的答案!