Ruby 单线程仍然处理并发请求?
Ruby进程是单线程的。当我们使用瘦服务器启动单个进程时,为什么我们仍然能够处理并发请求Ruby 单线程仍然处理并发请求?,ruby,multithreading,thin,Ruby,Multithreading,Thin,Ruby进程是单线程的。当我们使用瘦服务器启动单个进程时,为什么我们仍然能够处理并发请求 require 'sinatra' require 'thin' set :server, %w[thin] get '/test' do sleep 2 <---- "success" end 需要“sinatra” 需要“瘦” 设置:服务器%w[精简] 获取“/test”do 睡眠2引用章节:中的“非阻塞IOs/反应器模式” : 这是Twisted、EventMachine和Nod
require 'sinatra'
require 'thin'
set :server, %w[thin]
get '/test' do
sleep 2 <----
"success"
end
需要“sinatra”
需要“瘦”
设置:服务器%w[精简]
获取“/test”do
睡眠2引用章节:中的“非阻塞IOs/反应器模式”
:
这是Twisted、EventMachine和Node.js使用的方法。Ruby开发人员可以使用EventMachine或Node.js
基于EventMachine的Web服务器,如Thin和EM客户端/驱动程序,用于进行非阻塞异步调用。”
问题的核心在于
*
用于将阻塞操作集成到EventMachine的控制流中。
defer的操作是执行第一个参数中指定的块(“操作”)
并安排它在EventMachine维护的内部线程池上异步执行
当操作完成时,它将传递由块计算的结果(如果有)
回到反应堆。
然后,EventMachine调用第二个参数中指定的块以延迟(“回调”),
作为其正常事件处理循环的一部分
操作块计算的结果作为参数传递给回调。
如果操作完成后不需要执行任何代码,则可以省略回调参数。
*
本质上,为了响应HTTP请求,服务器执行您编写的,
调用connection类中的进程
方法。
查看$GEM\u HOME/gems/thin-1.6.2/lib/thin/connection.rb中的代码
:
服务器和客户端之间的连接。
#该类由EventMachine在每个新连接上实例化
#那是打开的。
类连接
#在收到所有数据和请求时调用
#已准备好进行处理。
def过程
如果有螺纹?
@request.threaded=true
延迟(方法(:预处理),方法(:后处理))
其他的
@request.threaded=false
后处理(前处理)
结束
结束
…这里是线程连接调用EventMachine.defer的地方
反应堆
查看在何处激活了
应遵循程序的初始化步骤:
请注意,对于所有Sinatra应用程序和中间件($GEM\u HOME/gems/Sinatra-1.4.5/base.rb
)
可以使用Thin、Puma、Mongrel或WEBrick作为自托管服务器运行Sinatra应用程序。
方法detect\u rack\u handler返回第一个rack::handler
return Rack::Handler.get(server\u name.to\s)
在我们的测试中,我们需要thin,因此它返回一个瘦机架处理程序并设置一个线程服务器
$GEM_HOME/gems/thin-1.6.2/lib/thin/server.rb
$GEM_HOME/gems/thin-1.6.2/lib/thin/backends/base.rb
Ruby不是单线程。嗨@Franco,回答是thx。所以在我看来,异步只是在HTTP连接上,当运行ruby代码时,它仍然是同步的,对吗?基本上是的。除了我的回答之外,搜索更多文档可能会有所帮助,例如,当您有时间时,您可以观看演示文稿,如:本演示文稿,如果发现有不清楚的地方,还可以搜索具体问题
def run!(options = {}, &block)
return if running?
set options
handler = detect_rack_handler
....
# Starts the server by running the Rack Handler.
def start_server(handler, server_settings, handler_name)
handler.run(self, server_settings) do |server|
....
server.threaded = settings.threaded if server.respond_to? :threaded=
# Start the server and listen for connections.
def start
raise ArgumentError, 'app required' unless @app
log_info "Thin web server (v#{VERSION::STRING} codename #{VERSION::CODENAME})"
...
log_info "Listening on #{@backend}, CTRL+C to stop"
@backend.start { setup_signals if @setup_signals }
end
# Start the backend and connect it.
def start
@stopping = false
starter = proc do
connect
yield if block_given?
@running = true
end
# Allow for early run up of eventmachine.
if EventMachine.reactor_running?
starter.call
else
@started_reactor = true
EventMachine.run(&starter)
end
end