ruby – 如何使用条件变量?

ruby – 如何使用条件变量?,第1张

概述Ruby中的条件变量资源不多,但大多数都是错误的.像 ruby-doc, tutorial here或 post here一样 – 所有人都可能陷入僵局. 我们可以通过以给定顺序启动线程来解决问题,并且可能在两者之间进行一些睡眠以强制执行同步.但那只是推迟了真正的问题. 我将代码重写为经典的producer-consumer problem: require 'thread'queue = [] Ruby中的条件变量资源不多,但大多数都是错误的.像 ruby-doc,tutorial here或 post here一样 – 所有人都可能陷入僵局.

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

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

require 'thread'queue = []mutex = Mutex.newresource = ConditionVariable.newthreads = []threads << Thread.new do  5.times do |i|    mutex.synchronize do       resource.wait(mutex)      value = queue.pop      print "consumed #{value}\n"    end  endendthreads << Thread.new do  5.times do |i|    mutex.synchronize do      queue << i      print "#{i} produced\n"      resource.signal    end    sleep(1) #simulate expense  endendthreads.each(&:join)

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

0 produced1 producedconsumed 02 producedconsumed 13 producedconsumed 24 producedconsumed 3producer-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.newresource = ConditionVariable.newthreads = []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  endendthreads << Thread.new do  5.times do |i|    mutex.synchronize do      queue << i      print "#{i} produced\n"      resource.signal    end    sleep(1) #simulate expense  endendthreads.each(&:join)
总结

以上是内存溢出为你收集整理的ruby – 如何使用条件变量?全部内容,希望文章能够帮你解决ruby – 如何使用条件变量?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1274735.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存