11

我试图理解 C 中的多线程编程。

我怀疑当我们使用 MUTEXES 进行线程同步时,为什么我们不能使用布尔变量来阻止要执行的代码的关键区域。

布尔变量静音的特点是什么?

PS:其实这个问题是在面试的时候问的。因此,请分享您对此的了解。

4

4 回答 4

14

问题是两个线程都可以同时看到布尔值可用,然后都认为继续是安全的。

例如,假设您有以下代码:

bool myLock = false;  // visible to all threads

void someFunction()
{
    if (!myLock)
    {
        myLock = true;
        // do whatever
        // and then release the lock
        mylock = false;
    }
}

现在,假设有两个线程正在执行。线程 A 读取myLock并看到它是false,因此它继续执行下一条指令。同时,线程 B 读取myLock并看到它是false,因为线程 A 尚未将其设置为true。所以线程 B 继续前进,也获得了锁。此时,两个线程都在执行本应受互斥锁保护的代码。

It gets worse because Thread A finishes what it's doing and sets mylock back to false while Thread B is still executing. So another thread can come along and take the lock even though Thread B is still in there.

A mutex guarantees atomicity. That is, it guarantees that the check-and-update can only be done by a single thread at a time. So if you replace the boolean with a mutex, you have:

if (mutex.Acquire())
{
    // do stuff
    // then release the lock
    mutex.Release();
}

There's no chance that two threads can acquire the mutex simultaneously.

于 2013-10-23T16:49:31.433 回答
2

如果您尝试将布尔值用作“假互斥锁”,我可以很容易地指出您的实现中的缺陷,直到您基本上重新发明互斥锁为止。互斥锁基本上是一个布尔值,其中包含用于线程同步所需的所有额外内容。

于 2013-10-23T06:17:35.240 回答
2
int locked = 0;
void lock( void ) {
    while ( locked ) sleep_api( little );
    locked = 1;
    return;
}

这段代码是错误的,因为两个线程可以同时看到locked变量中的0,并认为他们拥有了锁。

于 2013-10-23T07:37:01.363 回答
0

首先,你的建议并不完全清楚。假设您有五个线程都在竞争相同的资源。很清楚您将如何使用互斥锁来确保独占访问。目前还不清楚如何为此使用布尔变量。

也就是说,布尔变量有时可用于同步。但是,这适用的情况是有限的,并且有一些警告(例如,这些变量通常需要声明volatile)。

互斥锁的应用范围更广。可能值得一提的是,除了(正确地)确保只有一个线程可以进入受保护部分之外,它们还充当内存屏障

于 2013-10-23T06:15:28.857 回答