gpt4 book ai didi

ruby-on-rails - Ruby 默认是线程安全的吗?

转载 作者:太空宇宙 更新时间:2023-11-03 17:30:52 25 4
gpt4 key购买 nike

我在控制台中运行以下代码 10 多次,结果相同,100000

i = 0
1000.times do
Thread.start { 100.times { i += 1 } }
end
i

当我使用多个线程读取和更新 i 时,它不应该给我不同的输出吗?这让我想知道,默认情况下 ruby​​ 实际上是线程安全的吗?如果不是,那为什么我总是看到相同的输出?

附注如果你说,默认情况下它不是线程安全的,那么你能分享一个简单的例子,当我在 Rails 控制台中运行时,它会给我不同的结果吗?

编辑:

换句话说,上面的代码是否同时运行了 1000 个线程?如果是,则结果不应该是 100000 ALWAYS。如果不是,那么如何并发运行多个线程?

如果我添加puts,那么i 的打印顺序将会改变。这意味着线程相互交错,但它们是否同时运行?

我不是在问,如何使这个线程安全。我了解 mutex/locking 和同步/异步进程的概念。因为我理解它们,所以我无法理解这段代码的输出。

最佳答案

没有代码自动是线程安全的,您必须努力使其成为线程安全的。

特别是+=操作实际上是三个操作:read,increment,write。如果这些与其他线程混合在一起,您可能会遇到非常不可预测的行为。

考虑以下两个线程上的一系列事件:

  A       B
-------------
READ
READ
INCR
INCR
WRITE
WRITE

这是最简单的情况,您将有两个增量操作,因为它们都使用相同的原始值,其中一个被取消。

在我的测试中,这不太可能发生在双核系统上,但在四核机器上实际上是一个经常出现的问题,因为许多系统的行为就像两个松散连接的双核系统,每个系统都有自己的缓存。使用 JRuby 时更加明显线程支持要好得多。您的示例代码会为我生成随机答案,范围从 98200 到 99500。

为了使该线程安全,您必须使用Mutex 或使用像Concurrent Ruby 这样的库中的原子增量操作。这将为您提供安全执行此操作的工具。

替代方法是避免在线程之间混合数据或使用类似 Queue 的结构管理通信。如果没有 Mutex,任何两个线程都不应该操作同一个对象。

关于ruby-on-rails - Ruby 默认是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37997976/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com