访问同一变量的多个请求会导致冲突吗?

时间:2013-05-26 16:45:06

标签: ruby sinatra worker

尝试一些我不太熟悉的东西:

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

假设我每秒获得几千次点击/。如果在$log上同时调用push和pop会发生什么?

提高工作线程的优先级会有什么帮助吗?

1 个答案:

答案 0 :(得分:2)

您应该使用Queue来实现此目的,因为它适用于跨线程通信。它是线程安全的,并且保持线程不忙等待,因为Queue#pop将暂停线程,如果队列中没有任何内容而不是循环,直到操作系统取消控制权。

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

然而,你所拥有的不会是一个问题(因为意外的结果会导致性能问题),因为MRI GIL(其他没有GIL的Ruby实现可能会有问题)。此外,最好避免使用全局变量。