Rails:Sidekiq Workers必须是线程安全的。这是什么意思?

时间:2017-11-16 07:09:25

标签: ruby-on-rails ruby multithreading model-view-controller sidekiq

我读到了关于Sidekiq的信息:

Sidekiq是多线程的,所以你的工作者必须是线程安全的。

这是什么意思?什么是“线程安全”代码?有人可以举例说明吗?非常感谢你。

1 个答案:

答案 0 :(得分:5)

有许多方法可以获得非线程安全的代码。以下是非线程安全代码的一个示例:

# shared resource
$resource = StringIO.new

class NonThreadSafeWorker
  include Sidekiq::Worker

  def perform(_)
    random_letter = ('a'..'z').to_a.sample
    # concurrency problem: data race
    100_000.times do
      $resource.write random_letter
    end
  end
end

# Suppose you run 2 workers, result might be the next: "aaaabbabbabba..."

它是线程安全的补充:

require 'thread'

mutex = Mutex.new

class ThreadSafeWorker
  include Sidekiq::Worker

  def perform(_)
    random_letter = ('a'..'z').to_a.sample
    mutex.synchronize do
      # synchronize access to shared resource
      100_000.times do
        $resource.write random_letter
      end
    end
  end
end

# Suppose you run 2 workers, result must be the next: "aaaaaaa...bbbbbb..."

请注意,MRI GIL会在解释器级别强制执行唯一一个线程。但这并不意味着您不会遇到与上述类似的并发问题。 JRuby和Rubinius是“真正的”并发执行环境,但不太常见,正是因为许多库(包括标准版)应该在考虑线程安全的情况下进行重写。

Sidekiq不对您要在worker中使用的库负责,但是gracefully cautious您要了解使用非线程安全库的后果。