c++ - 导致 C++11 std::mutex 将阻塞的线程锁定为被动等待状态?

标签 c++ multithreading c++11

我有以下情况:

两个 C++11 线程正在计算,它们通过 std::mutex 同步。

线程 A 锁定互斥锁,直到数据准备好供线程 B 执行的操作使用。当互斥量解锁时,线程 B 开始工作。

线程 B 试图锁定互斥量并被阻塞,直到它被线程 A 解锁。

void ThreadA (std::mutex* mtx, char* data)
{
    mtx->lock();
    //do something useful with data
    mtx->unlock();
}

void ThreadB (std::mutex* mtx, char* data)
{
    mtx->lock(); //wait until Thread A is ready
    //do something useful with data
    //.....
}

断言Thread A可以先阻塞mutex。

现在我想知道线程 B 中的 mtx->lock() 是主动等待还是被动等待。线程 B 也是在轮询互斥锁状态并浪费处理器时间,或者在互斥锁解锁时被调度器被动释放。

在不同的C++引用资料中只提到线程被阻塞,但没有提到阻塞的方式。

但是,std::mutex 实现几乎不依赖于所使用的平台和操作系统吗?

最佳答案

它是高度实现定义的,即使对于相同的编译器和操作系统也是如此

例如,在 VC++ 上,在 Visual Studio 2010 中,std::mutex 是使用 Win32 CRITICAL_SECTION 实现的。 EnterCriticalSection(CRITICAL_SECTION*) 有一些不错的功能:首先,它会尝试通过迭代 一次又一次地锁定CRITICAL_SECTION。在指定的迭代次数之后,它会进行内核调用,使线程进入休眠状态,只有在释放锁并重新开始整个交易时才会再次唤醒。 在这种情况下,该机制在进入休眠之前一次又一次地轮询锁,然后控制权切换到内核。

Visual Studio 2012 带有不同的实现。 std::mutex 是用 Win32 mutex 实现的。 Win32 mutex 立即将控制转移到内核。锁没有进行主动轮询。

您可以在答案中阅读有关实现开关的信息:std::mutex performance compared to win32 CRITICAL_SECTION

因此,互斥量如何获取锁是未指定的。最好不要依赖这种行为。

附言。不要手动锁定互斥锁,而是使用 std::lock_guard。此外,您可能希望使用 condition_variable 来更精确地控制同步。

关于c++ - 导致 C++11 std::mutex 将阻塞的线程锁定为被动等待状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32950616/

相关文章:

c++ - 位标志是 std::byte 的预期用途吗?

c++ - 删除和替换 CAtlArray 中间的对象指针

c++ - 声明 C++ 中的冲突说明符

c# - Unity3d 中的多线程脚本调用

c++ Win32 Api GetMessage 线程内关闭程序

c++ - 试图区分不同类型的右值——文字和非文字

c++ - 处理对话框中的键盘输入 - Windows

c++ - 在类中初始化静态 vector 最方便的方法是什么?

Android Application.mk 设置能够使用 c++11 <random> 和 dynamic_cast

javascript - 了解 JavaScript 的单线程特性