Ruby 192递归线程锁错误

Ruby 192递归线程锁错误,ruby,multithreading,Ruby,Multithreading,我正在使用Ruby192P290:under-one单元测试脚本(如下所示)抛出ThreadError 1) 错误: 测试或通过测试(TC\U MyTest): 线程错误:死锁;递归锁 内部:前奏曲:8:在“锁”中 内部:前奏曲:8:在“同步”中 testth.rb:121:in'orchpr_run' testth.rb:158:in'test_或chpr_pass' ruby 187给出错误:线程试图加入自身。 代码 引发相同错误的另一段代码: require "thread" requ

我正在使用Ruby192P290:under-one单元测试脚本(如下所示)抛出ThreadError

1) 错误:

测试或通过测试(TC\U MyTest):

线程错误:死锁;递归锁

内部:前奏曲:8:在“锁”中

内部:前奏曲:8:在“同步”中

testth.rb:121:in'orchpr_run'

testth.rb:158:in'test_或chpr_pass'

ruby 187给出错误:线程试图加入自身。 代码 引发相同错误的另一段代码:

 require "thread"
 require "timeout"

 def calc_fib(n)
   if n == 0
     0
   elsif n == 1
     1
   else
     calc_fib(n-1) + calc_fib(n-2)
   end
 end

 lock = Mutex.new

 threads = 20.times.collect do
   Thread.new do
     20.times do
       begin
         Timeout.timeout(0.25) do
           lock.synchronize{ calc_fib(1000) }
         end
       rescue ThreadError => e
         puts "#{e.class}: #{e.message}:\n" + e.backtrace.join("\n") + "\n\n"
       rescue Timeout::Error => e
         #puts e.class
         nil
       end
     end
   end
 end

 threads.each{ |t| t.join }

注释同步块将导致错误消失,但随后线程无法同步。我在网上发现了一些东西,比如Ruby192的bug,需要在文件prelude.rbthread.c中更改互斥同步。
但是在windows安装下找不到文件prelude.rb

如果某个互斥锁被某个线程锁定,那么如果您尝试从同一个线程再次锁定它,将引发错误

这正是您所要做的,因为
synchronize
只是锁定互斥锁的一种方便方法,让位于块,然后释放锁。我不知道你想做什么,但我觉得你可能在尝试使用互斥体,而不是它们的预期用途


很好地使用线程和锁很难做到正确-您可能需要寻找一种不同的并发方法。

如果线程锁定了互斥锁,那么如果您尝试从同一线程再次锁定它,则会引发错误

这正是您所要做的,因为
synchronize
只是锁定互斥锁的一种方便方法,让位于块,然后释放锁。我不知道你想做什么,但我觉得你可能在尝试使用互斥体,而不是它们的预期用途


很好地使用线程和锁是很难做到的-您可能需要寻找一种不同的并发方法。

有两台服务器并排执行一段代码(线程模型),我只想在这两台服务器都完成处理时退出代码。我添加了另一段抛出相同错误的代码。看起来超时并没有导致synchronize释放锁,这很奇怪。不管怎样,这似乎是一个非常奇怪的互斥体用法。有两个服务器并排执行一段代码(线程模型),我只想在这两个服务器都完成处理时退出代码。我添加了另一段抛出相同错误的代码。看起来超时并没有导致synchronize释放锁,这很奇怪。无论如何,这似乎是一个非常奇怪的互斥使用。
 require "thread"
 require "timeout"

 def calc_fib(n)
   if n == 0
     0
   elsif n == 1
     1
   else
     calc_fib(n-1) + calc_fib(n-2)
   end
 end

 lock = Mutex.new

 threads = 20.times.collect do
   Thread.new do
     20.times do
       begin
         Timeout.timeout(0.25) do
           lock.synchronize{ calc_fib(1000) }
         end
       rescue ThreadError => e
         puts "#{e.class}: #{e.message}:\n" + e.backtrace.join("\n") + "\n\n"
       rescue Timeout::Error => e
         #puts e.class
         nil
       end
     end
   end
 end

 threads.each{ |t| t.join }