Weird deadlock problems with Slave/drb

P

Peter Lichten

#!/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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,968
Messages
2,570,149
Members
46,695
Latest member
StanleyDri

Latest Threads

Top