2017-10-19 22 views
0

クラスTalkerがあるとします。キューを使用して話し手の話をしていますが、話者をミュートしたい場合がありますが、話し手のミュートを解除すると、話し手は彼が中断したところでピックアップします。どのようにスレッドがメッセージをキューから取り出してから、話し手のミュートを解除して再開するまで待つのですか?Rubyでスレッドを処理キューから一時停止する

@handler = Class.new do 
    @locks = {} 

    def mute(id, mutex) 
    @locks[id] ||= mutex.lock 
    end 

    def unmute(id) 
    @locks[id].unlock if @locks[id].is_a?(Thread::Mutex) 
    @locks.delete(id) 
    end 
end 


Thread.new do 
    MX = Thread::Mutex.new 
    until @queue.empty? 
    MX.synchronize do 
     next_msg = @queue.shift 
     puts next_msg 
    end 
    end 
end 

# stop threads from taking messages from queue 
def mute 
    @handler.mute(self, MX) 
end 

# allow threads to continuing taking messages from queue 
def unmute 
    @handler.unmute(self) 
end 

コードがテストされていないが、私はそれが動作するはずと信じて:

class Talker 
    def initialize 
    @queue = Queue.new 
    @threads = Array.new(1) do 
     Thread.new do 
     until @queue.empty? 
      # what logic should go here to check if mute 
      # and stop taking messages? 
      next_msg = @queue.shift 

      puts next_msg 
     end 
     end 
    end 
    end 

    def speak(msg) 
    @queue.push(msg) 
    end 

    # stop threads from taking messages from queue 
    def mute 
    # what goes here? 
    end 

    # allow threads to continuing taking messages from queue 
    def unmute 
    # what goes here? 
    end 
end 

答えて

0

もののルビーは間違いなく非同期操作を処理するための最良の選択ではない、一つはまだThread::Mutexを利用することができます。

0

のではなく、スレッドごとのミューテックスを持つ、あなたはミューテックス

class Talker 
    def initialize 
    @muted = false 
    @muted_mutex = Thread::Mutex.new 

    @queue = Queue.new 
    @threads = Array.new(1) do 
     Thread.new do 
     until @queue.empty? 
      next if @muted # skip this iteration 
      puts @queue.shift 
     end 
     end 
    end 
    end 

    def mute 
    @muted_mutex.synchronize { @muted = true } 
    end 

    def unmute 
    @muted_mutex.synchronize { @muted = false } 
    end 
end 

で保護され、簡単なフラグを持つことができ、これとスレッドごとのミューテックスを持つとの違いは、複数のスレッド(場合にのみブロックすることです他の場所で)同時にミュート/ミュートを解除しようとします。しかし、@muted = falseとそれを読み込んでいるスレッドとの間に競争があるので、実際に停止しているスレッドとミュートの間に少しの遅延があるかもしれません。

おそらく良い習慣とは考えられませんが、もし私があなただったら、私はミューテックスを捨てるでしょう。ブールフラグの場合、複数の書き込みが同時に発生しても差はありません。

関連する問題