锁定信号量对象有意义吗?

问题描述 投票:0回答:2
我遇到了一段使用信号量作为锁定对象的代码。我向我的同事询问了这个问题,他们说,如果我们想监视锁的状态,或者如果代码深处发生奇怪的异常并且 CLR 无法回滚堆栈,或者其他什么情况,这可能很有意义这样,锁没有正常释放,我们可以手动释放它。

我从未听说过这些现象,也没有发现任何相关信息,所以我对整件事非常怀疑。我认为这只是一种不好的做法,因为您会对如何使用 Semaphore 对象感到困惑。有人可以确认一下吗?

private Semaphore _semaphore = new Semaphore(0, 1); public void DoSomethingThreadSafe() { lock (_semaphore) { //some code } }
    
c# locking semaphore
2个回答
1
投票
与任何其他对象类型相比,锁定信号量对象不会带来任何额外的好处,但可能会损害可读性,因为这不是执行此类操作的惯用方式:

如果我们想监控锁的状态

lock

 机制对于用于同步的对象类型绝对不可知,并且不会尝试将 
Semaphore
 实例与另一个实例区分开来以执行某些 
Semaphore
 特定的操作。实际发生的情况是, 
Monitor.Enter
Monitor.Exit
 方法用于 
lock
 构造的生成代码中,并且这些方法在内部与 CLR 对象标头(它是任何引用类型内存布局的一部分)和/或同步一起使用块是实例头引用的特殊表中的条目。因此,除了使用一些黑客方法来获取 CLR 维护的内部同步状态之外,没有其他方法可以监视用于同步的对象的状态。

或者如果代码深处发生了奇怪的异常,CLR无法回滚堆栈,或者类似的情况,并且锁没有正确释放,我们可以手动释放它

再次强调,信号量作为

Semaphore

 实例的状态与同步对象的状态无关,同步对象恰好是信号量实例内存布局的一部分,由 
lock
 机制内部使用,并且输入或离开 
lock
 块不会导致改变信号量计数,并且释放信号量也不会对用于 
lock
 的同步对象产生任何影响。因此,在这种情况下使用信号量不会带来任何好处,而且如果 CRL 无法展开堆栈时出现问题,那么应用程序代码在这种情况下能否执行某些操作就非常值得怀疑。


0
投票
当您尝试跨进程边界实现对资源的独占访问时,信号量和互斥体确实具有优势。这两个类都有接受

String

 参数的 c'tors。如果两个(或更多)进程使用相同的 
String
 值,则可以实现对资源的独占访问。 (显然,这种排他性是“自愿的,因为你必须为此进行编程)。

这些类可以确保单个进程中只有一个线程可以访问您感兴趣的任何资源。

© www.soinside.com 2019 - 2024. All rights reserved.