【问题标题】:Are YARV Arrays' push/pop methods thread-safe?YAAR Array 的 push/pop 方法是线程安全的吗?
【发布时间】:2018-08-13 19:20:17
【问题描述】:

假设我有一对(生产者、消费者)YARV 线程 (Tp,Tc) 共享一个 Array q - Tp 推送到 q,并从中弹出 Tc .如果 push 和 pop 的执行顺序不重要,代码是否可以在没有任何同步机制的情况下工作?

【问题讨论】:

    标签: ruby yarv


    【解决方案1】:

    由于其全局解释器锁 (GIL),大多数时间在 MRI/YARV 中访问数组是线程安全的(并且仅存在于那里),因此大多是偶然的。

    您仍然必须确保每次只执行一个操作并避免读/写结构。在 Rubinius 或 JRuby 等其他 Ruby 实现中,数组显然不是线程安全的。

    话虽如此,Ruby 为线程间通信提供了不同的原语,巧合的是,它是 MRI/VARV 中唯一明确线程安全的类:Queue。它支持以线程安全的方式推送和弹出对象。

    以 Ruby 文档中的这个例子为例:

    queue = Queue.new
    
    producer = Thread.new do
      5.times do |i|
         sleep rand(i) # simulate expense
         queue << i
         puts "#{i} produced"
      end
    end
    
    consumer = Thread.new do
      5.times do |i|
         value = queue.pop
         sleep rand(i/2) # simulate expense
         puts "consumed #{value}"
      end
    end
    

    还有一个维护良好的项目concurrent-ruby,它为跨线程并发编程提供了许多强大的原语。

    【讨论】:

    • 您能解释一下“您仍然必须确保每次只执行一个操作并避免读/写结构”的意思吗?
    • 好吧,像array[0] = array[1] +42 这样的操作不是线程安全的,因为在读取和写入之间可能存在重叠线程。您还必须确保一次只能从单个线程访问存储在数组/队列中的对象(或使用互斥锁来强制执行此操作)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-21
    • 1970-01-01
    • 2020-07-09
    • 1970-01-01
    • 2012-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多