gpt4 book ai didi

Ruby 线程安全线程创建

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

我今天遇到了这段代码:

@thread ||= Thread.new do
# this thread should only spin up once
end

它被多个线程调用。我担心如果多个线程正在调用此代码,您可能会创建多个线程,因为 @thread 访问不同步。但是,有人告诉我,由于全局解释器锁,这不可能发生。我阅读了一些有关 Ruby 中线程的内容,似乎运行 Ruby 代码的各个线程可能会被其他线程抢占。如果是这种情况,你不能有这样的交错:

Thread A             Thread B
======== ========
Read from @thread .
Thread.New .
[Thread A preempted] .
. Read from @thread
. Thread.New
. Write to @thread
Write to @thread

此外,由于对@thread 的访问不是同步的,因此对@thread 的写入是否保证对所有其他线程可见?我过去使用的其他语言的内存模型不能保证写入内存的可见性,除非您使用原子、互斥等同步对该内存的访问。

我仍在学习 Ruby,并且意识到要理解 Ruby 中的并发性还有很长的路要走。对此的任何帮助将不胜感激!

最佳答案

你需要一个互斥体。本质上,GIL 唯一保护你的是访问未初始化的内存。如果 Ruby 中的某些东西可以被明确定义而不是原子的,你不应该假设它是原子的。

一个简单的例子来说明你的例子排序是可能的。每次运行时我都会收到“double set”消息:

$global = nil
$thread = nil

threads = []

threads = Array.new(1000) do
Thread.new do
sleep 1
$thread ||= Thread.new do
if $global
warn "double set!"
else
$global = true
end
end
end
end

threads.each(&:join)

关于Ruby 线程安全线程创建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57660980/

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