线程安全的单次启动方法应该使用什么样的高级同步结构



我遇到一种情况,后台处理会话可以通过超时、用户异步取消或会话完成来完成。这些完成事件中的任何一个都可以运行单次射击完成方法。完成方法只能运行一次。假设会话是一个对象的实例,因此任何同步都必须使用实例构造。

目前,我正在对完成状态变量使用Atomic Compare and Swap操作,这样每个事件都可以在运行时测试和设置完成状态。要激发的第一个完成事件将设置完成状态并运行单次方法,其余事件将失败。这很好用。

然而,我忍不住觉得我应该能够以更高水平的方式做到这一点。我尝试使用Lock对象(NSLock,因为我用Cocoa写这篇文章),但随后收到警告,我正在释放一个仍处于锁定状态的锁。这当然是我想要的。锁被锁定了一次,但从未解锁,但我担心代表锁的系统资源可能会泄露。

不管怎样,我只是想知道是否有人知道一种更高水平的方法来实现这样的单杆方法。

任何完成事件的示例代码:

if(OSAtomicCompareAndSwapInt(0, 1, &completed))
{
    self.completionCallback();
}

执行CAS几乎可以肯定是正确的做法。锁不是为您需要的东西而设计的,它们可能要贵得多,而且无论如何在语义上都不匹配——完成不是"锁定的"。它已经"完成"了。布尔标志是正确的表示,执行CAS可以确保在并发场景中安全地操作它。在C++中,我会使用std::atomic_flag,也许可以检查Cocoa是否有类似的东西(这只是将CAS封装在一个更好的界面中,这样你就不会意外地在变量上使用非CAS测试,这会很有趣)。

(编辑:在pthreads中,有一个名为pthread_once的函数,它可以实现您想要的功能,但我不知道Cocoa;在我看来,pthread_once接口无论如何都很难处理…)

最新更新