我正在使用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尝试加入自身。
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
答案 0 :(得分:0)
如果某个线程锁定了互斥锁,那么如果您尝试从同一个线程再次锁定它,则会引发错误
这正是你正在做的事情,因为synchronize
只是方便锁定互斥锁,产生块然后释放锁的方法。我不确定你要做什么,但我觉得你可能会尝试将互斥量用于非预期目的。
很难正确使用线程和锁定 - 您可能希望查看celluloid以获得不同的并发方法。