使用Soap4r在ruby中进行线程锁定

时间:2009-10-20 20:36:51

标签: ruby multithreading soap4r

这与我在这里提出的问题有关: Thread Locking in Ruby (use of soap4r and QT)

然而,这个问题的一部分是特别的,并且由一个更简单的例子支持。测试代码是:

require 'rubygems'
require 'thread'
require 'soap/rpc/standaloneserver'

class SOAPServer < SOAP::RPC::StandaloneServer

    def initialize(* args)
        super
        # Exposed methods
        add_method(self, 'test', 'x', 'y')
    end

    def test(x, y)
        return x + y
    end
end


myServer = SOAPServer.new('monitorservice', 'urn:ruby:MonitorService', 'localhost',         4004)

Thread.new do
    puts 'Starting web services'
    myServer.start
    puts 'Ending web services'
end

sleep(4)

#Thread.new do
    testnum = 0
    while testnum < 4000 do
        testnum += 1
        puts myServer.test(0,testnum)
        sleep(2)
    end
#end

puts myServer.test(0,4001)
puts myServer.test(0,4002)
puts myServer.test(0,4003)
puts myServer.test(0,4004)
gets

当我运行这个线程注释掉时,一切都很顺利。但是,一旦线程被放入进程挂起。我戳进了Webrick,发现停止发生在这里(看跌期权当然是我的):

while @status == :Running
      begin
        puts "1.1"
        if svrs = IO.select(@listeners, nil, nil, 2.0)
          svrs[0].each{|svr|
        puts "-+-"
            @tokens.pop          # blocks while no token is there.
            if sock = accept_client(svr)
              th = start_thread(sock, &block)
              th[:WEBrickThread] = true
              thgroup.add(th)
            else
              @tokens.push(nil)
            end
          }
        end
        puts ".+."

当使用未注释的线程运行时,我得到这样的结果: 启动Web服务

1.1
.+.
1.1
4001
4002
4003
4004
1
.+.
1.1

2 个答案:

答案 0 :(得分:1)

如果问题是由gets()调用引起的,并且代码中的gets()调用的目的是阻止Ruby解释器退出,则可以用Thread.join()调用替换每个线程你创造。 Join()将阻塞,直到该线程完成执行,因此它将阻止Ruby解释器退出。

E.g:

t1 = Thread.new do
    puts 'Starting web services'
    myServer.start
    puts 'Ending web services'
end

t2 = ...
...

t1.join
t2.join

或者,如果只有一个线程控制应用程序的执行,你可以加入()只有一个线程,其他线程将在退出时被终止。

答案 1 :(得分:0)

尾随获取Ruby的IO。我不知道为什么。如果它被几乎任何东西取代,程序就可以工作。我用了一个睡眠循环:

loop do
    sleep 1
end

增加: 我应该注意到,基于睡眠增量,我也会因睡眠而出现奇怪的行为。最后我放弃了Ruby,因为线程行为实在太糟糕了。