The*_*hop 10 ruby multithreading ruby-on-rails actioncontroller
我有一组数据,我想在我的rails应用程序内部进行一些计算,每个计算是相互独立的,所以我想对它们进行处理,所以我的响应要快得多.
这就是我所拥有的ATM:
def show
@stats = Stats.new
Thread.new {
@stats.top_brands = #RESULT OF FIRST CALCULATION
}
Thread.new {
@stats.top_retailers = #RESULT OF SECOND CALCULATION
}
Thread.new {
@stats.top_styles = #RESULT OF THIRD CALCULATION
}
Thread.new {
@stats.top_colors = #RESULT OF FOURTH CALCULATION
}
render json: @stats
end
Run Code Online (Sandbox Code Playgroud)
现在,这会为每个成员实例返回一堆空数组@stats,但是,如果我将这些线程连接在一起,它就会运行,但是由于每个线程阻塞而无法实现线程化的目的.
因为我对线程很新,所以我想知道我在这里做错了什么,或者它是否有可能完成我正在尝试做的事情,也就是说,在paralell中运行4个计算并将结果返回给客户端.
谢谢,
乔
Die*_*zar 12
首先取决于您的计算是在进行处理器繁重的操作,还是在执行大量阻塞IO,例如从数据库,文件系统或网络中读取数据.如果它们正在执行前者,那将不会有太大的好处,因为每个线程占用CPU时间并且没有其他线程可以安排 - 即使您使用具有全局解释器锁的 Ruby MRI也会更糟.但是如果线程正在阻塞IO,那么它们至少可以等待,让另一个线程运行,等待,让另一个运行等等,直到它们全部返回.
最后,您必须将所有线程连接在一起,因为您需要它们的返回值.在所有Thread.new调用下面执行此操作.将每个Thread.new的返回值保存到数组:
threads = []
threads << Thread.new ...
Run Code Online (Sandbox Code Playgroud)
然后在渲染之前将它们连接在一起:
threads.each &:join
Run Code Online (Sandbox Code Playgroud)
如果你真的想确定这可以帮助你只是对整个行动进行基准测试:
def show
start_time = Time.now.to_f
@stats = Stats.new
Thread.new {
@stats.top_brands = #RESULT OF FIRST CALCULATION
}
Thread.new {
@stats.top_colors = #RESULT OF FOURTH CALCULATION
}
@elapsed_time = Time.now.to_f - start_time
# do something with @elapsed_time, like putsing it or rendering it in your response
render json: @stats
end
Run Code Online (Sandbox Code Playgroud)
希望有所帮助.