0

根据cppreferencestd::lock_guard ,使用参数构造 an会std::mutex调用lock()that 的方法mutex

根据cplusplus,关于mutex'slock()方法:

如果互斥锁被另一个线程锁定,则调用线程的执行将被阻塞,直到被另一个线程解锁...

我不确定名义上的问题是否措辞正确,因此我将其放在以下代码的上下文中。

我想对此进行测试,看看调用线程是否真的在等待解锁,而不是终止其可调用对象(例如函数、仿函数、lambda)的执行和/或抛出异常。下面的代码有两个线程t1t2每个线程都有一个指向同一个函数的指针foo。在执行锁保护代码之前,每次调用foo都会sleep_for有一定的时间,由foounsigned参数决定。num锁保护代码本身包含另一个sleep_for周期,以使任何阻塞的执行周期更加明显:

#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>

std::mutex m;

void foo(unsigned num) {
    std::this_thread::sleep_for(std::chrono::milliseconds(num * 10));
    std::lock_guard<std::mutex> guard(m);
    std::this_thread::sleep_for(std::chrono::milliseconds(3000));
    std::cout << num << std::endl;
}

int main() {
    std::thread t1(foo, 10);
    std::thread t2(foo, 5);
    t1.join();
    t2.join();
}

控制台输出:

5
10

输出大约/至少需要 3.05 秒5。输出需要大约/至少额外 3 秒10。这意味着t2首先执行受保护的代码,因为它在锁定mutex.

我假设一旦对foofrom 线程的调用t1到达该lock_guard行并发现mutex已经被 锁定t2t1不会终止执行或引发异常。t1只是等待它被解锁。

多久检查一次解锁std::mutex::lock()std::lock_guard支票有多贵?检查是否执行如下?

while (some_mutex.try_lock() == false) {
    std::this_thread::sleep_for(std::chrono::milliseconds(1))
}
// execute lock-protected code
4

2 回答 2

4

std::mutex::lock() 或 std::lock_guard 多久进行一次解锁检查?

它没有。它在操作系统内部阻塞,直到资源被释放。任何通过旋转来实现这一点的操作系统都会引起抱怨。

于 2014-01-10T02:00:40.190 回答
2

互斥锁通常由操作系统提供,这意味着您的操作系统的线程模型负责所有这些。这些细节根本没有被 C++ 指定甚至实现。

因此,在某种程度上,它将取决于许多因素,例如所有进程的 CPU 负载、相对进程优先级、相对线程优先级......

即使这样的事情很有用,也有太多事情无法为您提供明确的答案。

于 2014-01-10T01:35:05.337 回答