Bug #21037
openRactors hang with multiple threads
Description
The following program hangs, but I don't expect it to hang:
# frozen_string_literal: true
class Map
def initialize
@r = Ractor.new {
cache = { "int" => "integer", "bool" => "boolean" }
loop do
key = receive
Ractor.yield key
end
}
freeze
end
def fetch(key)
@r.send key
m = @r.take
raise unless key == m
m
end
end
tm = Map.new
t1 = Thread.new { 10.times { |i| p [i + 1,tm.fetch("int")] } }
t2 = Thread.new { 10.times { |i| p [i + 1, tm.fetch("bool")] } }
t1.join
t2.join
I'm not sure why this program hangs yet, but it does both on macOS and Linux. I've tested with master, Ruby 3.4, and Ruby 3.3. I'm not sure why it's hanging yet, but I wanted to file an issue.
Updated by luke-gru (Luke Gruber) about 1 month ago
· Edited
Maybe this fixes it? https://github.com/ruby/ruby/pull/12520
Edit: I just tried with this branch but it seems unrelated. If you run with RUBY_DEBUG it fails an assertion having to do with ractor sleep (the receive
call). I'll take a look when I get a chance.
Updated by luke-gru (Luke Gruber) about 1 month ago
· Edited
It seems calling ractor.take
from multiple threads is unsupported at the moment. I don't know if this is a limitation or a bug. Of course, you can work around it and call select
or take
from a single thread, like main, and signal a ready event with a queue or something for the consumer threads.
Edit: There are some TODOs in the codebase having to do with waiting threads for ractors, and they explicitly say "TODO: make multithreaded". I believe this is a known problem, at least for @ko1 (Koichi Sasada).
Updated by luke-gru (Luke Gruber) 29 days ago
· Edited
I created a PR here: https://github.com/ruby/ruby/pull/12633. I don't know how to get it working for Win32 builds yet, I'll have to take a closer look at that.
Edit: Everything works now except for Visual Studio 2022, I'm trying to setup a Windows VM to see what's failing.