我有方法a
在某个随机时间重复调用,从而触发方法b
,它在一段随机时间后完全执行,并且在它自己的线程中。我想确保随后执行a
等到b
已完成,由当前执行触发a
。换句话说,a
and b
均须交替执行。我尝试使用互斥体和条件变量来执行此操作,如下所示:
def a
Thread.new do
$mutex.synchronize do
puts "a"
b
$cv.wait($mutex)
end
end
end
def b
Thread.new do
sleep(rand)
$mutex.synchronize do
puts "b"
$cv.signal
end
end
end
$mutex, $cv = Mutex.new, ConditionVariable.new
loop{a; sleep(rand)}
在这段代码中,$mutex.synchronize do ... end
在方法中a
确保$cv.signal
(也在另一个$mutex.synchronize do ... end
) 在方法中b
直到$cv.wait($mutex)
sets $cv
进入信号监听模式。这么多是在该文件 http://ruby-doc.org/stdlib-2.0.0/libdoc/thread/rdoc/ConditionVariable.html.
我打算分配给的另一个功能$mutex.synchronize do ... end
在方法中a
是为了避免方法的连续执行a
。我的理由是$cv.wait($mutex)
在方法中a
应该避免$mutex
从完成并发布直至$cv.signal
在方法中b
被调用,此时b
应该完成。
我期望a
and b
交替执行,从而打印"a"
and "b"
或者。但事实上,它们并非如此。每一个"a"
or "b"
可以连续打印。
之后,我认为我上面的推理可能是错误的,因为$mutex
即使已经完成并发布$cv
(or $mutex
) 处于等待模式,一次$cv.wait($mutex)
已经called。所以我添加了一些虚拟进程a
,将其更改为:
def a
Thread.new do
$mutex.synchronize do
puts "a"
b
$cv.wait($mutex)
nil # Dummy process intended to keep `$mutex` locked until `$cv` is released
end
end
end
但这没有效果。
如何解决这个问题?或者说,我这件事有什么错吗?
我没有办法给你解决办法,但这不是原因a
接到的电话比您预期的要多wait
释放互斥锁上的锁?否则signal
永远无法被调用。这似乎第一次“如预期”发生,但在那之后,你最终会得到几个a
线程排队,渴望进入synchronize
块,他们在一个b
线程唤醒并再次锁定互斥体。
如果你每次都对你的代码进行检测,你会看到它发生:
def a
puts("a before thread #{Thread.current}")
Thread.new do
puts(" a synch0 #{Thread.current}")
$mutex.synchronize do
puts(" a before b #{Thread.current}")
b
puts(" a after b, before wait #{Thread.current}")
$cv.wait($mutex)
puts(" a after wait #{Thread.current}")
end
puts(" a synch1 #{Thread.current}")
end
puts("a after thread #{Thread.current}")
end
def b
puts("b before thread #{Thread.current}")
Thread.new do
puts(" b before sleep #{Thread.current}")
sleep(rand)
puts(" b after sleep, synch0 #{Thread.current}")
$mutex.synchronize do
puts(" b before signal #{Thread.current}")
$cv.signal
puts(" b after signal #{Thread.current}")
end
puts(" b synch1 #{Thread.current}")
end
puts("b after thread #{Thread.current}")
end
$mutex, $cv = Mutex.new, ConditionVariable.new
loop{a; sleep(rand)}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)