【问题标题】:Help with OSSpinLock* usage to replace a while(true) {sleep(1);}帮助使用 OSSpinLock* 替换 while(true) {sleep(1);}
【发布时间】:2009-04-08 15:45:42
【问题描述】:

我在 OS X 上维护一个 carbon C++ 应用程序。代码中的一个对象中有一个“自旋锁”,如下所示,

while ( mState != RELEASED )
{
    sleep( 1 );
}

有一个提供给 AudioUnitAddRenderNotify() 的渲染后维护回调,它将设置这些不同对象的 mState。

我正在考虑使用内置的 OSSpinLock 系列函数来替换它(如果没有别的,因为它们是线程安全的,而上面的代码似乎不是)。

这是一个合理的等价物吗?我是否还应该在操作这些对象的 mState 的维护线程中添加一些锁定保护?

OSSpinLock spin_lock = OS_SPINLOCK_INIT;

if (!OSSpinLockTry(&spin_lock))
    OSSpinLockLock(&spin_lock);

while (mState != RELEASED)
    OSSpinLockTry(&spin_lock);

OSSpinLockUnlock(&spin_lock);

【问题讨论】:

    标签: c++ macos macos-carbon


    【解决方案1】:

    不要使用自旋锁——自旋锁会浪费 CPU 周期,无限循环直到获得锁。只有在持有锁的时间很短时才应使用自旋锁。

    更好的选择是使用condition variable,例如pthreads 库中提供的那些。这样,在满足条件之前,您的线程将休眠并且不会浪费任何 CPU 周期。请参阅该链接中列出的示例,了解如何使用 pthreads 条件变量。

    【讨论】:

    • 根据应用程序的不同,自旋锁可以比最终跳入内核或更糟的对象执行得更好,从而导致上下文切换。但是,这仍然是一组有限的应用程序,应谨慎使用。
    • 操作系统提供的自旋锁(例如 OSSpinLock)比它们将要替换的“普通”自旋锁(例如“while (1) {}”)要好得多。他们比你认为的更聪明;例如,OSSpinLockLock 使用回退策略来避免活锁。 developer.apple.com/documentation/Darwin/Reference/ManPages/…
    • 也就是说,对于这种特定情况,来自 pthread 或 Cocoa (NSConditionLock) 的条件变量是更好的选择。
    猜你喜欢
    • 2012-01-16
    • 2015-12-22
    • 2020-02-22
    • 2011-11-10
    • 1970-01-01
    • 2021-08-24
    • 1970-01-01
    • 2012-12-13
    • 1970-01-01
    相关资源
    最近更新 更多