简体   繁体   中英

Ruby thread safe thread creation

I came across this bit of code today:

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

It is being called by multiple threads. I was worried that if multiple threads are calling this code that you could have multiple threads created since @thread access is not synchronized. However, I was told that this could not happen because of the Global Interpreter Lock. I did a little bit of reading about threads in Ruby and it seems like individual threads that are running Ruby code can get preempted by other threads. If this is the case, couldn't you have an interleaving like this:

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

Additionally, since access to @thread is not synchronized are writes to @thread guaranteed to be visible to all other threads? The memory models of other languages I've used in the past do not guarantee visibility of writes to memory unless you synchronize access to that memory using atomics, mutexes, etc.

I'm still learning Ruby and realize I have a long way to go to understanding concurrency in Ruby. Any help on this would be super appreciated!

You need a mutex. Essentially the only thing the GIL protects you from is accessing uninitialized memory. If something in Ruby could be well-defined without being atomic, you should not assume it is atomic.

A simple example to show that your example ordering is possible. I get the "double set" message every time I run it:

$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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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