1

これは、私がここで尋ねた質問に関連しています: Ruby でのスレッド ロック (soap4r と 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
4

2 に答える 2

1

問題の原因が gets() 呼び出しであり、コード内の gets() 呼び出しの目的が Ruby インタープリターの終了を防ぐことである場合は、作成するスレッドごとに Thread.join() 呼び出しに置き換えることができます。Join() はそのスレッドの実行が完了するまでブロックするため、Ruby インタープリターが終了できなくなります。

例えば:

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

t2 = ...
...

t1.join
t2.join

または、アプリケーションの実行を制御する単一のスレッドがあり、他のスレッドが終了時に強制終了される場合に、スレッドの 1 つだけを join() できる場合。

于 2010-01-12T10:26:41.837 に答える
0

末尾の get は Ruby の IO をブロックします。理由はわかりません。それがほとんど何でも置き換えられれば、プログラムは動作します。私は睡眠ループを使用しました:

loop do
    sleep 1
end

追加: 睡眠の増分に基づいて、睡眠でも奇妙な動作が発生することに注意してください。最終的に、スレッドの振る舞いがあまりにも不安定だったため、Ruby を放棄しました。

于 2009-10-27T16:05:40.387 に答える