c++ - 为什么我的两个线程之一永远不会获得互斥锁?
问题描述
我有两个线程,两个线程都有一个可以做一些工作的循环。两者之间唯一真正的行为差异是线程 1sleep_for
在将其互斥锁锁定在循环中之前执行,线程 2 没有。目标是保持系统上的线程 1:我不希望它 100% 地锤击 CPU。线程 2 本质上是临时的,所以它不应该在工作时休眠。但是线程 2 所做的工作量(每次迭代)很重(因此sleep_for
在我的示例中,在锁定之后,以模拟由于实际工作而长期持有的锁定)。
线程 2 获取所有执行时间。事实上,线程 1 仅在 4 秒后进行了 1 次迭代。我期望线程 1 锁定std::mutex
,等待解锁,然后获取锁。不std::mutex
充当某种队列吗?意思是,即使线程 2 在获取锁之前没有休眠,但当它尝试锁定下一次迭代时,它最终不得不等待锁被释放,因为线程 1 是下一个获取锁的?即使在那里睡觉,我希望每个线程 1 和线程 2 都可以轮流。
我在这里错在哪里?这种行为的解释是什么?C++ 标准提供了哪些保证,哪些不是?
#include <thread>
#include <atomic>
#include <mutex>
#include <iostream>
#include <chrono>
using namespace std::chrono_literals;
std::unique_lock<std::mutex> LockMutex()
{
static std::mutex m;
return std::unique_lock<std::mutex>{m};
}
int main()
{
std::atomic_bool running{true};
std::thread t1{[&] {
while (running)
{
std::this_thread::sleep_for(100ms);
auto lock = LockMutex();
std::cout << "Thread 1 :: Time Slice\n";
}
}};
std::thread t2{[&] {
while (running)
{
auto lock = LockMutex();
std::cout << "Thread 2 :: Time Slice\n";
std::this_thread::sleep_for(100ms);
}
}};
std::this_thread::sleep_for(4s);
running = false;
t1.join();
t2.join();
}
我得到的输出是:
Start
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 2 :: Time Slice
Thread 1 :: Time Slice
0
Finish
用于测试的实时代码示例。