繁体   English   中英

旋转锁实现(OSSpinLock)

[英]Spin Lock Implementations (OSSpinLock)

我刚刚开始研究多线程编程和线程安全性。 我熟悉忙碌等待,经过一些研究后,我现在熟悉自旋锁背后的理论,所以我想我会看一下OSSpinLock在Mac上的实现。 它归结为以下函数(在objc-os.h中定义):

static inline void ARRSpinLockLock(ARRSpinLock *l)
{
again:
   /* ... Busy-waiting ... */
    thread_switch(THREAD_NULL, SWITCH_OPTION_DEPRESS, 1);
    goto again;
}

完全实施

在做了一些挖掘之后,我现在已经大致了解了thread_switch的参数是什么( 这个站点是我发现它的地方)。 我对我所读到的内容的解释是,对thread_switch的这一特定调用将切换到下一个可用线程,并将当前线程的优先级降低到1个周期的绝对最小值。 '最终'(在CPU时间内)此线程将再次变为活动状态并立即再次执行goto again; 重新开始忙碌等待的指令。

我的问题是,为什么这个电话实际上是必要的? 我发现了一个自旋锁的另一种实现方式(适用于Windows这段时间), 在这里 ,它不包括(Windows的当量)的线程切换调用的。

您可以通过多种不同方式实现自旋锁。 如果您找到另一个针对Windows的SpinLock实现,您将看到另一种算法(它可能涉及SetThreadPrioritySleepSwitchToThread )。

ARRSpinLockLock默认实现非常聪明,在第一个旋转周期后,它“ ARRSpinLockLock ”一段时间的线程优先级,这具有以下优点:

  • 它为拥有锁的线程提供了更多机会释放它;
  • 它浪费了更少的CPU时间 (和功率 !)执行NOPPAUSE

Windows实现不会这样做,因为Windows API不提供该机会(没有等效的thread_switch()函数,并且对SetThreadPriority多次调用可能效率较低)。

我实际上并不认为他们是那么不同。 在第一种情况下:

static inline void ARRSpinLockLock(ARRSpinLock *l)
{
    unsigned y;
again:
    if (__builtin_expect(__sync_lock_test_and_set(l, 1), 0) == 0) {
        return;
    }
    for (y = 1000; y; y--) {
#if defined(__i386__) || defined(__x86_64__)
        asm("pause");
#endif
        if (*l == 0) goto again;
    }
    thread_switch(THREAD_NULL, SWITCH_OPTION_DEPRESS, 1);
    goto again;
}

我们试图获得锁定。 如果失败了,我们在for循环中旋转,如果它在此期间可用,我们会立即尝试重新获取它,如果不是,我们放弃CPU。

在另一种情况下:

inline void Enter(void)
{
    int prev_s;
    do
    {
        prev_s = TestAndSet(&m_s, 0);
        if (m_s == 0 && prev_s == 1)
        {
            break;
        }
        // reluinquish current timeslice (can only
        // be used when OS available and
        // we do NOT want to 'spin')
        // HWSleep(0);
    }
    while (true);
}

请注意if下面的注释,它实际上表示如果操作系统为我们提供该选项,我们可以旋转或放弃CPU。 事实上,第二个例子似乎只是让那个部分留给程序员[插入你在这里继续代码的首选方式],所以从某种意义上说它不像第一个那样完整的实现。

我对整个事情的看法,我正在评论第一个片段,就是他们试图在能够快速获得锁定(1000次迭代)和不过多地占用CPU之间取得平衡(因此我们如果锁不可用,最终会切换。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM