如何用监视器替换该信号量?
在我之前的问题中,有人表示与使用监视器相比,在 C# 中使用信号量的成本更高。所以我问,如何用监视器替换这段代码中的信号量?
我需要 function1 在 function2 (在单独的线程中)完成后返回其值。我已将 Semaphore.WaitOne
替换为 Monitor.Wait
,将 Semaphore.Release
替换为 Monitor.PulseAll
但 PulseAll
在 Wait
之前被触发,导致程序挂起。知道如何避免这种竞争条件吗?
Semaphore semaphore = new Semaphore(0,1);
byte b;
public byte Function1()
{
// new thread starting in Function2;
semaphore.WaitOne();
return b;
}
public void Function2()
{
// do some thing
b = 0;
semaphore.Release();
}
In previous question of mine, someone had meantioned that using Semaphores were expensive in C# compared to using a monitor. So I ask this, how can I replace the semaphore in this code with a monitor?
I need function1 to return its value after function2 (in a separate thread) has been completed. I had replaced the Semaphore.WaitOne
with a Monitor.Wait
and the Semaphore.Release
with a Monitor.PulseAll
but the PulseAll
was being triggered before the Wait
causing the program to hang. Any idea how to avoid that race condition?
Semaphore semaphore = new Semaphore(0,1);
byte b;
public byte Function1()
{
// new thread starting in Function2;
semaphore.WaitOne();
return b;
}
public void Function2()
{
// do some thing
b = 0;
semaphore.Release();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以使用 WaitHandle 而不是信号量来完成此操作。这将是最简单的替代方案,并且比信号量表现更好:
You can do this with a WaitHandle instead of a Semaphore. This would be the simplest alternative, and perform better than a Semaphore:
@Reed 提供了一个 优雅的解决方案 如果需要等待多个线程。
您可能不想为此使用
Monitor
。正如 @Reed 指出的,一个事件就足够了,并且可以提供符合您的代码要求的最干净、最易于理解的解决方案。
在您的情况下,使用真实操作系统同步原语的开销很可能并不重要,并且使用例如
Monitor
只会以更高的复杂性为代价提供递减的回报。话虽如此,这里是使用
Monitor
和信令的实现。您可以使用由锁保护的
bool
标志来指示您已完成并避免在这种情况下等待。 (一)如果您确实在
Function2()
中启动一个新线程,其中注释指出并在 两者 周围使用lock()
WaitOne()< /code> 和
Release()
,您根本不需要该标志。 (B)A,使用标志:
B,从
Function1
启动线程:@Reed provided an elegant solution if you need to wait for multiple threads.
You might not want to use
Monitor
fro this.As @Reed pointed out, an event would suffice and would provide the cleanest and most understandable solution that matches the requirements of your code.
The overhead of using real operating system sync primitives will most probably not matter in your case and using e.g.
Monitor
would provide only diminishing returns at the cost of much higher complexity.With that said, here is an implementation using
Monitor
and signaling.You can use a
bool
flag - guarded by the lock - to indicate that you have finished and avoid waiting in that case. (A)If you really start a new thread within
Function2()
where the comments indicate and uselock()
around bothWaitOne()
andRelease()
, you do not need the flag at all. (B)A, using a flag:
B, starting a thread from
Function1
: