gpt4 book ai didi

ruby - 在 Ruby 中实现同步屏障

转载 作者:行者123 更新时间:2023-12-02 17:11:44 31 4
gpt4 key购买 nike

我正在尝试“复制”CUDA __synchtreads() 的行为Ruby 中的函数。具体来说,我有一组N需要执行某些代码的线程,然后在继续执行其余业务之前,所有线程都在执行中点互相等待。例如:

x = 0

a = Thread.new do
x = 1
syncthreads()
end

b = Thread.new do
syncthreads()
# x should have been changed
raise if x == 0
end

[a,b].each { |t| t.join }

我需要使用什么工具来完成此任务?我尝试使用全局哈希,然后休眠,直到所有线程都设置了一个标志,表明它们已完成代码的第一部分。我无法让它正常工作;它导致挂起和死锁。我认为我需要使用 Mutex 的组合和ConditionVariable但我不确定为什么/如何。

编辑: 50 次浏览,无人回复!看起来像是赏金的候选人......

最佳答案

让我们实现一个同步屏障。它必须预先知道它将处理的线程数,n。在前 n - 1 次调用 sync 期间,屏障将导致调用线程等待。调用号n将唤醒所有线程。

class Barrier
def initialize(count)
@mutex = Mutex.new
@cond = ConditionVariable.new
@count = count
end

def sync
@mutex.synchronize do
@count -= 1
if @count > 0
@cond.wait @mutex
else
@cond.broadcast
end
end
end
end

sync 的整体是一个临界区,即它不能由两个线程同时执行。因此调用 Mutex#synchronize

@count的减少值为正时,线程被卡住。将互斥体作为参数传递给 ConditionVariable#wait 的调用对于防止死锁至关重要。它会导致互斥体在卡住线程之前解锁。

一个简单的实验启动 1k 线程并使它们向数组添加元素。首先他们添加零,然后同步并添加1。预期结果是一个具有 2k 个元素的排序数组,其中 1k 个是 0,1k 个是 1。

mtx = Mutex.new
arr = []
num = 1000
barrier = Barrier.new num
num.times.map do
Thread.start do
mtx.synchronize { arr << 0 }
barrier.sync
mtx.synchronize { arr << 1 }
end
end .map &:join;
# Prints true. See it break by deleting `barrier.sync`.
puts [
arr.sort == arr,
arr.count == 2 * num,
arr.count(&:zero?) == num,
arr.uniq == [0, 1],
].all?

事实上,有 a gem named barrier这正是我上面描述的。

最后一点,在这种情况下不要使用 sleep 来等待。这称为忙等待is considered a bad practice .

关于ruby - 在 Ruby 中实现同步屏障,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13765839/

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