Ruby 监视器分段错误

发布于 2024-07-17 11:35:03 字数 736 浏览 3 评论 0原文

我按照 http://www.ruby-doc 中的示例进行操作.org/stdlib/libdoc/monitor/rdoc/index.html 并稍微修改了代码:

require 'monitor.rb'

buf = []
buf.extend(MonitorMixin)
empty_cond = buf.new_cond

producer = Thread.start do
# producer
line = "produce at #{Time.now}"
#while line
  buf.synchronize do
    puts "==> #{line}"
    buf.push(line)
    empty_cond.signal
  end
  sleep(2)
  #line = "produce at #{Time.now}"
#end
end

loop do
   buf.synchronize do
      empty_cond.wait_while { buf.empty? }
      item = buf.shift
      puts "got #{item.inspect}"
   end
end

我让程序运行。 大约 5 分钟后,它抛出“分段错误”。 与僵局有关吗?

/杰克

I followed the example from http://www.ruby-doc.org/stdlib/libdoc/monitor/rdoc/index.html and modified the code a bit:

require 'monitor.rb'

buf = []
buf.extend(MonitorMixin)
empty_cond = buf.new_cond

producer = Thread.start do
# producer
line = "produce at #{Time.now}"
#while line
  buf.synchronize do
    puts "==> #{line}"
    buf.push(line)
    empty_cond.signal
  end
  sleep(2)
  #line = "produce at #{Time.now}"
#end
end

loop do
   buf.synchronize do
      empty_cond.wait_while { buf.empty? }
      item = buf.shift
      puts "got #{item.inspect}"
   end
end

I let the program run. Around 5 min later, it throws a "Segmentation fault". Something related to a deadlock?

/Jack

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

秋千易 2024-07-24 11:35:03

正如您的代码所示(在生产者循环中注释掉 while 语句),生产者线程只需运行循环一次并退出。 消费者从 buf 中读取生成的一行,然后陷入僵局,等待更多永远不会到达的行。

Ruby 的线程调度程序具有内置的死锁检测功能,因此当它发现“消费者”循环出现死锁时,它将终止程序。

要亲自查看死锁,请将生产者转换为全局变量 $ Producer 并使用 $consumer = Thread.start do ... end 包装循环语句。 将代码加载到 irb 并评估 $ Producer 应该会导致 => #< 主题:0x000000010afb58 死了> (以及睡眠线程中的 $consumer)

取出与生产者 while 循环相关的注释,您将拥有一个工作(无限)循环,它以 2 秒的间隔生成当前时间。

As your code stands (with the commented out while-statement in producer-loop) the producer thread simply runs through the loop once and exits. The consumer reads the one produced line from buf and then is left in a deadlock waiting for more lines that will never arrive.

Ruby's Thread scheduler has inbuilt deadlock-detection, so it will terminate the program when it sees that the 'consumer'-loop has deadlocked.

To see the deadlock for yourself, turn the producer into a global variable $producer and wrap the loop-statement with $consumer = Thread.start do ... end. Loading the code into irb and evaluating $producer should result in => #< Thread:0x000000010afb58 dead > (and $consumer in a sleeping thread)

Take out the comments relating to producer's while-loop and you'll have a working (infinite) loop that produces the current time at 2 second intervals.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文