繁体   English   中英

Ruby线程安全的线程创建

[英]Ruby thread safe thread creation

我今天遇到了这段代码:

@thread ||= Thread.new do
  # this thread should only spin up once
end

它被多个线程调用。 我担心如果多个线程正在调用此代码,由于@thread访问未同步,您可能会创建多个线程。 但是,有人告诉我,由于全局解释器锁定,这不可能发生。 我做了一些关于Ruby中线程的阅读,看来运行Ruby代码的单个线程可能会被其他线程抢占。 如果是这种情况,您是否不能像这样进行交错:

Thread A             Thread B
========             ========
Read from @thread    .
Thread.New           .
[Thread A preempted] .
.                    Read from @thread
.                    Thread.New
.                    Write to @thread
Write to @thread

另外,由于对@thread的访问未同步, @thread保证对@thread写入对所有其他线程可见? 除非您使用原子,互斥锁等同步访问该内存,否则我过去使用的其他语言的内存模型不能保证对内存写入的可见性。

我仍在学习Ruby,并且意识到要理解Ruby中的并发性还有很长的路要走。 任何帮助,将不胜感激!

您需要一个互斥锁。 本质上,GIL保护您免受攻击的唯一一件事就是访问未初始化的内存。 如果Ruby中的某些东西可以被很好地定义而不是原子的,那么您不应该假定它是原子的。

一个简单的示例说明您可以进行示例排序。 每次运行时,都会收到“双重设置”消息:

$global = nil
$thread = nil

threads = []

threads = Array.new(1000) do
  Thread.new do
    sleep 1
    $thread ||= Thread.new do
      if $global
        warn "double set!"
      else
        $global = true
      end
    end
  end
end

threads.each(&:join)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM