From: Peter Lichten Date: 2007-06-30T06:22:52+09:00 Subject: Weird deadlock problems with Slave/drb #!/usr/bin/env ruby # Original program idea: # Write a ruby program that checks the integrity of all my FLAC music files, # and that makes use of my MacBooks Core Duo CPU. Since Ruby doesn't support # native threadds, I decided to use the Slave library. # # Problem: # I start 3 Slave servers: # worker1 and worker2 both query the filename server to get the next filename # to process. # # On Mac OS 10.4.10, ruby 1.8.6 (Locomotive or MacPorts, same problem) the second # worker server process never starts, it seems to sleep forver, and I don't # see my programming mistake. # # The same problem occurs on Ubuntu Feisty. # # However: IF you start the 2nd worker after the first worker completed its # work, it runs without problem. # # And: If you disable the call to the filename server, both workers run # in parallel, too, without deadlocking. # # So the problem has something to do with both workers trying to access the # same filename server. # # Any ideas? require 'slave' require 'monitor' require 'fastthread' class FlacTestServer def processFiles(filenameServer) 50.times do |i| #sleep(0.02) #Activate this: #puts("PID #{ Process.pid }: Iteration #{ i }") #and disable this and both workers will run without worker 2 sleeping forever. puts("#{ Process.pid }: #{ filenameServer.nextFilename() }") end end end class FilenameServer include MonitorMixin def initialize() super @counter = 0 end def nextFilename() synchronize do # Return some dummy data @counter += 1 "#{ Process.pid }, #{ @counter }" end end end if $0 == __FILE__ fnServer = Slave.new() { FilenameServer.new() }.object worker1 = Slave.object({:async => true, :psname => 'Worker1'}) { FlacTestServer.new().processFiles(fnServer) } # "Works" if you activate this: #worker1.join() worker2 = Slave.object({:async => true, :psname => 'Worker2'}) { FlacTestServer.new().processFiles(fnServer) } # If you create the slaves using the following method instead, worker2 sometimes runs, sometimes not # and sometimes it runs only a few internal iterations before it sleeps forever / deadlocks...?!? # But you can get it to work if you active the sleep call in line 37. #ftServer1 = Slave.new() { FlacTestServer.new() }.object() #ftServer2 = Slave.new() { FlacTestServer.new() }.object() # #worker1 = Thread.new() { ftServer1.processFiles(fnServer) } #worker2 = Thread.new() { ftServer2.processFiles(fnServer) } worker1.join() puts("Worker 1 terminated.") #puts("Worker 2 status: #{ worker2.status() }") until worker2.join(0.15) worker2.join() puts("Worker 2 terminated.") puts("End main program: #{Process.pid}") end -- Posted via http://www.ruby-forum.com/.