通过futex实现锁定

问题描述 投票:0回答:1

我读了ostep书。我停在关于线程锁的章节上。通过 futex 实现互斥:

void mutex_lock(int *mutex)
{
    int v;
    if (atomic_bit_test_set(mutex, 31) == 0)
        return;
    atomic_increment(mutex);
    while(1)
    {
        if (atomic_bit_test_set(mutex, 31) == 0)
        {
            atomic_decrement(mutex);
            return;
        }
        v = *mutex; 
        if (v >= 0)
            continue;
        futex_wait(mutex, v);
    }
}

void mutex_unlock(int *mutex)
{
    if (atomic_add_zero(mutex, 0x80000000)) // (1)
        return;
    // <-- (here)
    futex_wake(mutex); // (2)
}

我不明白为什么我们需要这三行:

v = *mutex;
if (v >= 0)
    continue;

让我们考虑所有的可能性。什么时候可以呢?如果某个线程(第一个)获取了锁并想要释放它,则另一个线程(第二个)处于 while 循环中,如果是这样 => (1) 情况不能,因为在循环外我们增加互斥量,这意味着我们在(这里)并且 *mutex 现在 >= 0 => 调度程序中断 第一个线程(此处)并切换到第二个线程,我认为只有在这种情况下我们才需要这些行(我不知道其他可能性),但为什么我们不能删除它们?如果我们删除它们,第二个线程就会进入睡眠状态,例如futex 队列,当调度程序切换到第一个线程时,他会唤醒第二个线程 (2)。

c concurrency operating-system mutex futex
1个回答
0
投票

因为无论如何你都必须将值传递给

futex_wait
,所以你不妨在那里再做一次机会主义检查。

仅当 *mutex 的值没有从 v 改变时,futex_wait 系统调用才会挂起线程。

© www.soinside.com 2019 - 2024. All rights reserved.