Ruby 请教一个线程安全的问题

LongLonghaoran · 2020年12月29日 · 最后由 LongLonghaoran 回复于 2020年12月29日 · 377 次阅读

本意是想模拟一下线程不安全的情况

本意是想模拟一下线程不安全的情况,于是写了一下代码,创建 2 个线程共用 1 个变量,每个线程里面将共用变量 number 减 1

arr = []
number = 10
2.times do |i|
    arr << Thread.new do
        puts "t#{i} 剩余#{number}颗豆子\n"
        while(number != 0 ) do
            sleep(1)
            puts "t#{i} 剩余#{number}颗豆子\n"
            number -= 1
            # puts "t#{i} 减去1颗后,剩余#{number}颗豆子\n"
        end
    end
end

但是一旦将 puts 语句放在 number -= 1 下方,就又不会出现这种问题了,这到底是为何😕

arr = []
number = 10
2.times do |i|
    arr << Thread.new do
        puts "t#{i} 剩余#{number}颗豆子\n"
        while(number != 0 ) do
            sleep(1)
            #puts "t#{i} 剩余#{number}颗豆子\n"
            number -= 1
            puts "t#{i} 减去1颗后,剩余#{number}颗豆子\n"
        end
    end
end

puts 是一个 IO 操作,可以看作是一个很短暂的 sleep,这样 2-1=1 的线程有很大几率等到 1-1=0 的线程,一起退出循环。多跑几次下面的代码也会有减到 -1 的情况。

试了下,第二种方式也会遇到减到 -1 的情况

piecehealth 回复

不好意思,是我说错了,是的第二步多走几次也会出现这种

spike76 回复

嗯嗯,是的,我这个问题提的有点问题,之所以第一个例子下的 puts 输出 2 个相同的数的原因是因为前面一行使用了 sleep(1) 增加了竞争几率,在这一秒钟里很容易出现线程让出 cpu 时间给另一个线程执行的情况

LongLonghaoran 关闭了讨论。 12月29日 22:55
需要 登录 后方可回复, 如果你还没有账号请 注册新账号