[英]Locking an array of std::mutex using a std::lock_guard array
I have the following array of mutexes:我有以下互斥体数组:
std::mutex mtx[5];
And I would like to lock them all with an RAII style:我想用 RAII 风格锁定它们:
std::lock_guard<std::mutex> grd[5] { mtx[0], mtx[1], mtx[2], mtx[3], mtx[4] };
While the above code works, it isn't ideal as I can't write it independently of the size of the array (here 5).虽然上面的代码有效,但它并不理想,因为我不能独立于数组的大小(这里是 5)编写它。
Is there a way to do that?有没有办法做到这一点? Shall I work with template magic to create an
std::initializer_list
out of an array?我应该使用模板魔法从数组中创建一个
std::initializer_list
吗? (is that possible?) (那可能吗?)
I'm open to using std::array
or std::vector
instead of C-style arrays, I used those here for conciseness.我愿意使用
std::array
或std::vector
代替 C 风格的 arrays,我在这里使用它们是为了简洁。 Ideally this works in C++14 but any solution up to latest standards is fine.理想情况下,这适用于 C++14,但任何符合最新标准的解决方案都可以。
What you want is std::scoped_lock
.你想要的是
std::scoped_lock
。 It takes N mutexes and locks them on creation and unlocks on destruction.它需要 N 个互斥体并在创建时锁定它们并在销毁时解锁。 That would give you
那会给你
std::scoped_lock sl{mtx[0], mtx[1], mtx[2], mtx[3], mtx[4]};
If that's still too verbose you can wrap that in a factory function like如果这仍然太冗长,您可以将其包装在工厂 function 中,例如
// function that actually creates the lock
template<typename Mutexes, std::size_t N, std::size_t... Is>
auto make_scoped_lock(Mutexes (&mutexes)[N], std::index_sequence<Is...>)
{
return std::scoped_lock{mutexes[Is]...};
}
// helper function so you don't have to create your own index_sequence
template<typename Mutexes, std::size_t N>
auto make_scoped_lock(Mutexes (&mutexes)[N])
{
return make_scoped_lock(mutexes, std::make_index_sequence<N>{});
}
int main()
{
std::mutex mtx[5];
auto lock = make_scoped_lock(mtx);
}
If you switch to using a std::array
to hold the mutexes then the code can be simplified to a call to std::apply
to do the expansion of the array into a parameter pack like如果您切换到使用
std::array
来保存互斥体,那么代码可以简化为对std::apply
的调用以将数组扩展为参数包,例如
template<typename Mutexes>
auto make_scoped_lock(Mutexes& mutexes)
{
return std::apply([](auto&... mutexes) { return std::scoped_lock{mutexes...}; },
mutexes);
}
int main()
{
std::array<std::mutex, 5> mtx;
auto sl = make_scoped_lock(mtx);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.