加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby – 如何使用条件变量?

发布时间:2020-12-17 02:19:14 所属栏目:百科 来源:网络整理
导读:Ruby中的条件变量资源不多,但大多数都是错误的.像 ruby-doc,tutorial here或 post here一样 – 所有人都可能陷入僵局. 我们可以通过以给定顺序启动线程来解决问题,并且可能在两者之间进行一些睡眠以强制执行同步.但那只是推迟了真正的问题. 我将代码重写为经
Ruby中的条件变量资源不多,但大多数都是错误的.像 ruby-doc,tutorial here或 post here一样 – 所有人都可能陷入僵局.

我们可以通过以给定顺序启动线程来解决问题,并且可能在两者之间进行一些睡眠以强制执行同步.但那只是推迟了真正的问题.

我将代码重写为经典的producer-consumer problem:

require 'thread'
queue = []
mutex = Mutex.new
resource = ConditionVariable.new
threads = []

threads << Thread.new do
  5.times do |i|
    mutex.synchronize do 
      resource.wait(mutex)
      value = queue.pop
      print "consumed #{value}n"
    end
  end
end

threads << Thread.new do
  5.times do |i|
    mutex.synchronize do
      queue << i
      print "#{i} producedn"
      resource.signal
    end
    sleep(1) #simulate expense
  end
end

threads.each(&:join)

有时你会得到这个(但并不总是):

0 produced
1 produced
consumed 0
2 produced
consumed 1
3 produced
consumed 2
4 produced
consumed 3
producer-consumer.rb:30:in `join': deadlock detected (fatal)
        from producer-consumer.rb:30:in `each'
        from producer-consumer.rb:30:in `<main>'

什么是正确的解决方案?

解决方法

问题在于,正如您之前评论的那样,只有在您可以保证消费者线程在程序开始时首先获取互斥锁时,此方法才有效.如果不是这种情况,则会发生死锁,因为生成器线程的第一个resource.signal将在使用者线程尚未等待资源时发送.因此,第一个resource.signal基本上不会执行任何操作,因此您最终会调用resource.signal 4次(因为第一个丢失),而resource.wait则调用5次.这意味着消费者将永远等待,并发生死锁.

幸运的是,我们可以通过仅允许消费者线程开始等待来解决这个问题,如果没有更多的即时工作可用.

require 'thread'
queue = []
mutex = Mutex.new
resource = ConditionVariable.new
threads = []

threads << Thread.new do
  5.times do |i|
    mutex.synchronize do
      if queue.empty?
        resource.wait(mutex)
      end
      value = queue.pop
      print "consumed #{value}n"
    end
  end
end

threads << Thread.new do
  5.times do |i|
    mutex.synchronize do
      queue << i
      print "#{i} producedn"
      resource.signal
    end
    sleep(1) #simulate expense
  end
end

threads.each(&:join)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读