自旋锁实现(OSSpinLock) [英] Spin Lock Implementations (OSSpinLock)

查看:151
本文介绍了自旋锁实现(OSSpinLock)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚开始寻找到多线程编程和线程安全。我所熟悉的忙等待和一些研究之后,我现在熟悉的自旋锁背后的理论,所以我想我会看看OSSpinLock的Mac上执行。它归结为以下功能(在objc-os.h定义):

I am just starting to look into multi-threaded programming and thread safety. I am familiar with busy-waiting and after a bit of research I am now familiar with the theory behind spin locks, so I thought I would have a look at OSSpinLock's implementation on the Mac. It boils down to the following function (defined in objc-os.h):

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

全面落实这里

做了一些挖后,我现在有一个大致想法是什么 thread_switch 的参数做(的这个网站是,我发现它)。什么我已阅读我的跨pretation是,要thread_switch这个特殊的呼叫将切换到下一个可用线程,并减少当前线程的优先级降到最低1个周期。 '最终'(CPU时间),这个线程将活跃起来,并立即再次执行跳转; 指令,开始忙着等待一遍

After doing a bit of digging, I now have an approximate idea of what thread_switch's parameters do (this site is where I found it). My interpretation of what I have read is that this particular call to thread_switch will switch to the next available thread, and decrease the current thread's priority to an absolute minimum for 1 cycle. 'Eventually' (in CPU time) this thread will become active again and immediately execute the goto again; instruction which starts the busy-waiting all over again.

我的问题虽然,这是为什么调用实际上有必要吗?我发现了一个自旋锁的另一种实现方式(适用于Windows这段时间)的这里,它不包括(Windows的当量)螺纹交换呼叫都没有。

My question though, is why is this call actually necessary? I found another implementation of a spin-lock (for Windows this time) here and it doesn't include a (Windows-equivalent) thread switching call at all.

推荐答案

其实我不认为他们是不同的。在第一种情况:

I actually don't think they're that different. In the first case:

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;
}

我们试图获取锁。如果失败,我们旋转在循环,如果它已经成为在此期间,可我们立即尝试重新获得它,如果不是我们放弃CPU。

We try to acquire the lock. If that fails, we spin in the for loop and if it's become available in the meantime we immediately try to reacquire it, if not we relinquish the 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);
}

请注意下面的如果注释,这实际上说,我们既可以旋转或放弃CPU,如果操作系统为我们提供了选择。事实上第二个例子似乎刚刚离开的那部分由程序员[插入$ P $这里继续code的pferred方式],因此,在某种意义上,它不象第一个完整实现。

Note the comment below the if, which actually says that we could either spin or relinquish the CPU if the OS gives us that option. In fact the second example seems to just leave that part up to the programmer [insert your preferred way of continuing the code here], so in a sense it's not a complete implementation like the first one.

我作为在整个事情,与我评论的第一个片段,是他们正在努力实现能够快速获得锁之间的平衡(在1000次迭代),而不是占用CPU的太多(因此我们最终切换,如果锁不可用)。

My take on the whole thing, and I'm commenting on the first snippet, is that they're trying to achieve a balance between being able to get the lock fast (within 1000 iterations) and not hogging the CPU too much (hence we eventually switch if the lock does not become available).

这篇关于自旋锁实现(OSSpinLock)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆