使用 std::mutex 保护环路

Protecting for loop with std::mutex

本文关键字:保护环路 mutex 使用 std      更新时间:2023-10-16

我需要使用 std::mutex 保护数据容器,该容器用于 for 循环,如下所示:

for (auto it = data.begin(); it != data.end(); ++it)
{
std::cout << it->param;
...
}

我可以想到几个选项,但它们像这样丑陋:

{ // artificial scope
std::scoped_lock lock(myMutex)
for (auto it = data.begin(); it != data.end(); ++it)
{
std::cout << it->param;
...
}
}

有没有一种好看的方法来实现这一点? 我正在考虑类似以下内容(C++17(,但这无法编译。:(

for (std::scoped_lock lock(myMutex), auto it = data.begin(); it != data.end(); ++it)

for (auto [lock, it] = std::pair(std::scoped_lock lock(myMutex), data.begin()); it != data.end(); ++it)

> C++20 引入了带有初始值设定项的基于范围的 for 循环:

for (std::scoped_lock lock(myMutex); auto &&x : data)
{
std::cout << x.param;
}

GCC 9 和 Clang 8 已支持此功能,但需要-std=c++2a标志。

正如评论中所建议的那样,我不会忽视将"丑陋"块提取到单独方法中的明显解决方案。但你也可以做

std::unique_lock<std::mutex> guard(mutex);
for (auto it = data.begin(); it != data.end(); ++it) {
// ...
}
guard.unlock();

如果您不打算自己松开锁,则更喜欢std::lock_guard而不是std::unique_lock;scoped_lock也旨在锁定多个互斥锁。