gpt4 book ai didi

ruby - Ruby 中的多线程

转载 作者:数据小太阳 更新时间:2023-10-29 08:42:46 25 4
gpt4 key购买 nike

我需要创建 3 个线程。每个线程将在屏幕上打印颜色并休眠 x 秒。线程 A 将打印红色;线程 B 将打印黄色;线程 C 将打印绿色;

所有线程必须等到轮到它们打印。第一个打印的线程必须是 Red,打印完后,Red 会告诉 Yellow 轮到它打印,依此类推。线程必须能够打印多次(用户特定)

我卡住了,因为在 Thread 外部调用 @firstFlag.signal 不起作用,而且 3 个线程没有按正确的顺序工作如何让红色线程先走?

到目前为止我的代码:

@lock = Mutex.new
@firstFlag = ConditionVariable.new
@secondFlag = ConditionVariable.new
@thirdFlag = ConditionVariable.new

print "Tell me n's vallue:"
@n = gets.to_i

@threads = Array.new

@threads << Thread.new() {
t = Random.rand(1..3)
n = 0
@lock.synchronize {
for i in 0...@n do
@firstFlag.wait(@lock, t)
puts "red : #{t}s"
sleep(t)
@secondFlag.signal
end
}
}

@threads << Thread.new() {
t = Random.rand(1..3)
n = 0
@lock.synchronize {
for i in 0...@n do
@secondFlag.wait(@lock, t)
puts "yellow : #{t}s"
sleep(t)
@thirdFlag.signal
end
}
}

@threads << Thread.new() {
t = Random.rand(1..3)
n = 0
@lock.synchronize {
for i in 0...@n do
@thirdFlag.wait(@lock, t)
puts "green : #{t}s"
sleep(t)
@firstFlag.signal
end
}
}

@threads.each {|t| t.join}
@firstFlag.signal

最佳答案

您的代码中存在三个错误:

第一个错误

您的 wait 调用使用超时。这意味着您的线程将变得与您的预期顺序不同步,因为超时将使每个线程滑过您的预期等待点。

解决方案:将所有等待调用更改为不使用超时:

@xxxxFlag.wait(@lock)

第二个漏洞

您将序列触发器放在 Thread.join 调用的最后。您的 join 调用永远不会返回,因此您代码中的最后一条语句永远不会执行,您的线程序列也永远不会启动。

解决方案:更改顺序,先发出信号序列开始,然后加入线程:

@firstFlag.signal
@threads.each {|t| t.join}

第三个漏洞

wait/signal 构造的问题是它不缓冲信号。因此,您必须确保所有线程在调用 signal 之前都处于它们的 wait 状态,否则您可能会遇到线程调用 signal 之前的竞争条件另一个线程调用了 wait

解决方案:这有点难解决,虽然可以用Queue解决。但我建议您彻底重新考虑您的代码。请参阅下面的完整解决方案。


更好的解决方案

我认为您需要重新考虑整个构造,而不是条件变量,只需使用 Queue 即可。现在代码变得不那么脆弱了,因为 Queue 本身是线程安全的,您不再需要任何临界区。

Queue 的优点是您可以像使用 wait/signal 结构一样使用它,但它缓冲信号,这在这种情况下使一切变得更加简单。

现在我们可以重写代码了:

redq    = Queue.new
yellowq = Queue.new
greenq = Queue.new

然后每个线程变成这样:

@threads << Thread.new() {
t = Random.rand(1..3)
n = 0

for i in 0...@n do
redq.pop
puts "red : #{t}s"
sleep(t)
yellowq.push(1)
end
}

最后开始整个序列:

redq.push(1)
@threads.each { |t| t.join }

关于ruby - Ruby 中的多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51886719/

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