mutex::lock() 检查一次解锁状态是否已经被另一个线程锁定?

How frequently does mutex::lock() check for the unlocked state if it's already locked by another thread?

本文关键字:另一个 锁定 是否 线程 解锁 检查 lock mutex 一次 状态      更新时间:2023-10-16

根据cppreference,使用std::mutex参数构造std::lock_guard会调用该mutexlock()方法。

根据cplusplus,关于mutexlock()方法:

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

我不确定这个有名无实的问题措辞是否正确,所以我把它放在下面代码的上下文中。

我想测试一下,看看调用线程是否真的在等待解锁,而不是终止其可调用(例如函数、函数、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

5的输出大约/至少需要3.05秒。10的输出大约/至少需要额外的3秒。这意味着t2可以首先执行受保护的代码,因为它在锁定mutex之前的等待时间更短。

我假设一旦线程t1foo的调用到达lock_guard行并发现mutex已经被t2锁定,t1就不会终止执行或引发异常。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

std::mutex::lock()或std::lock_guard检查解锁的频率有多高?

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

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

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

有太多的事情要给你一个明确的答案,即使这样的事情会很有用。

相关文章: