为啥不建议从 finally 子句中调用二进制信号量的 release() 方法?

Posted

技术标签:

【中文标题】为啥不建议从 finally 子句中调用二进制信号量的 release() 方法?【英文标题】:Why it isn't advised to call the release() method of a binary semaphore from inside a finally-clause?为什么不建议从 finally 子句中调用二进制信号量的 release() 方法? 【发布时间】:2012-02-25 09:15:53 【问题描述】:

为了确保 Lock 被解锁,建议从 finally 子句中调用 unlock() 方法:

lock.lock();
try
  // critical section which may throw exceptions
 finally 
  lock.unlock();

这是为了避免可能的死锁,以防临界区的代码抛出异常。

为什么不建议在等效场景中对二进制信号量采用相同的做法?

mutex.acquire();
try
  // critical section which may throw exceptions
 finally 
  mutex.release();

【问题讨论】:

【参考方案1】:

我会说这通常是处理它们的最佳方式。然而,信号量可以由单独的线程释放,因此在一些高级用例中,这种模式是不可能的。 (也就是说,Lock lock()unlock() 调用可能在不同的方法中,因此也无法使用 finally 块)。

【讨论】:

【参考方案2】:

因为在二进制信号量上等待成功的线程不一定是发出信号的线程。线程不像获取互斥锁那样拥有信号量单元——任何线程都可以发出信号量信号(因此它们通常用于生产者-消费者队列)。

【讨论】:

【参考方案3】:

我建议这样做。但是信号量和锁的主要区别在于信号量没有所有者。这意味着获取信号量的线程可能不是释放它的线程,这没关系。我建议总是在某个时候在 finally 块中发布

【讨论】:

以上是关于为啥不建议从 finally 子句中调用二进制信号量的 release() 方法?的主要内容,如果未能解决你的问题,请参考以下文章

第18章 finally子句

为啥不能在 Redshift 的 CTE 的某些子句中调用不可变的 UDF?

为啥不调用 finalize()? [复制]

为啥我必须在析构函数中调用 MPI.Finalize() ?

java方法的参数 为啥有时会加上final关键字

为啥在传输和处理需要数字信号编成二进制码