문제

Trying something out I'm not very familiar with:

require 'sinatra'
require 'redis'

$redis = # Connect Redis
$log = []

Thread.new do
  while true do
    $redis.set 'test', $log.pop
  end
end

post '/' do
    $log.push(request.user_agent)
    "ok"
end

Say that I get a couple of thousand hits per second to /. What happens if push and pop are called simultaneously on $log?

Will raising the priority of the worker thread help anything?

도움이 되었습니까?

해결책

You should use use a Queue for this, as it is meant for cross-thread communication. It is thread-safe, and keeps the Thread from busy-waiting as Queue#pop will suspend the thread if there is nothing on the queue instead of looping till the OS takes control away.

require 'redis'
require 'sinatra'
require 'thread'

$redis = # Connect Redis
$log = Queue.new

Thread.new do
  while entry = $log.pop
    $redis.set 'test', entry
  end
end

post '/' do
  $log.push(request.user_agent)
  "ok"
end

However, what you have won’t be an issue (as far as unexpected results go—performance will be a problem) because of MRI’s GIL (other Ruby implementations without a GIL may have issues, though). Also, it would be best to avoid using global variables.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top