5

在多线程(2线程)程序中,我有以下代码:

while(-1)
{
    m.lock();

    (...)

    m.unlock();
}

m是一个互斥体(在我的情况下是 c++11 std::mutex,但我认为如果我使用不同的库它不会改变)。

假设第一个线程拥有互斥锁并且它(...)部分做了一些事情。第二个线程试图获取互斥锁,但它正在等待第一个线程 release m

问题是:当线程 1 结束它的(...)执行并解锁互斥锁时,我们能否确定线程 2 获得了互斥锁,或者线程 1 可以在线程 2 之前再次重新获得互斥锁,让它卡在里面lock()

4

5 回答 5

4

C++ 标准不对互斥锁的顺序锁定做出任何保证。因此,活动线程完全有可能在没有另一个线程尝试获取锁unlock()的情况下一直保持访问状态。我不认为 C++ 标准提供了一种控制线程优先级的方法。我不知道您要做什么,但可能还有另一种方法可以避免您遇到的问题。lock()std::mutex m

于 2012-12-21T22:22:31.080 回答
3

If both threads are equal priority, there is no such guarantee by standard mutex implementations. Some OS's have a lis of "who's waiting", and will pick the "longest waiting" when you release something, but that is an implementation detail, not something you can reliably depend on.

And imagine that you have two threads, each running something like this:

m.lock();

(...)

m.unlock();
(...)    // Clearly not the same code as above (...)
m.lock();

(...)    // Some other code that needs locking against updates. 

m.unlock();

Would you want the above code to switch thread on the second lock, every time?

By the way, if both threads run with lock for the entire loop, what is the point of a lock?

于 2012-12-21T22:16:16.450 回答
1

没有任何保证,因为线程之间没有以任何方式相互排序。事实上,唯一的同步点互斥锁。

第一个线程完全有可能立即重新获取锁,例如,如果它在紧密循环中运行该函数。如果任何线程在互斥锁上休眠,典型的实现具有通知和唤醒机制,但也可能存在让正在运行的线程继续而不是执行上下文切换的偏见......这在很大程度上取决于实现和细节当时的平台。

于 2012-12-21T22:25:23.487 回答
1

C++ 或底层操作系统不提供任何保证。

但是,线程到达临界区(在这种情况下为互斥体)的时间决定了某种合理程度的公平性。这种公平性可以表示为统计概率,但不是严格的保证。这种选择很可能取决于操作系统执行调度程序,它还将考虑许多其他因素。

于 2012-12-22T00:02:35.080 回答
-1

依赖这样的代码不是一个好主意,所以你可能应该改变你的设计。但是,在某些操作系统上, sleep(0) 会产生线程。(Windows 上的睡眠(0))同样,最好不要依赖这个。

于 2012-12-21T23:02:47.137 回答