Ruby 192递归线程锁定错误

时间:2013-05-23 10:23:11

标签: ruby multithreading

我正在使用ruby 192 p290:在一个单元测试脚本下(如下所示)抛出ThreadError

  

1)错误:

     
    

test_orchpr_pass(TC_MyTest):

         

ThreadError:死锁;递归锁定

         

内部:前奏:8:在'lock'

         

内部:前奏:8:在'同步'

         

testth.rb:121:在`orchpr_run'

         

testth.rb:158:在`test_orchpr_pass'

  
     

使用ruby 187会出错:Thread尝试加入自身。

CODE

def orchpr_run(timeout = 60)


    # used by the update function to signal that a final update was
    # received from all clients

    @update_mutex.lock

    # required since we'll have to act as an observer to the DRb server
    DRb.start_service

    # get configuration objects
    run_config_type = DataLayer.get_run_config_type
    client_daemon = DataLayer.get_client_daemon_by_branch (run_config_type, @branch)
            client_daemon['port_no'] = 9096
            #get the servers for this client_daemon
    servers = DataLayer.get_servers(run_config_type, client_daemon.id)

    servers.each { |server| @pr[server.host_name] = OrchestratedPlatformRun.new(run_config_type, server, timeout) 

    }

    @pr.each_value { |x| x.add_observer(self) 

    @pr.each_value { |x| x.start(@service_command_pass, true) 


    # wait for update to receive notifications from all servers # this is the statement causing error:
    @update_mutex.synchronize {} end

另一段代码抛出相同的错误:

 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 }

注释同步阻止将导致错误消失,但随后线程无法同步。我在网上找到了一些东西,说ruby 192的bug,需要修改文件 prelude.rb thread.c 关于MUTEX同步。 但在Windows安装下无法找到文件 prelude.rb

1 个答案:

答案 0 :(得分:0)

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

这正是你正在做的事情,因为synchronize只是方便锁定互斥锁,产生块然后释放锁的方法。我不确定你要做什么,但我觉得你可能会尝试将互斥量用于非预期目的。

很难正确使用线程和锁定 - 您可能希望查看celluloid以获得不同的并发方法。