在函数中创建多个lock_guards

Creating multiple lock_guards in a function

本文关键字:lock guards 函数 创建      更新时间:2023-10-16

我有一个类,其中包含一个充满指向 std::mutex 对象的指针的向量(数量是可变的,具体取决于用户操作(和一个成员函数。在这个函数中,我想执行一些操作,但我需要在执行这些操作之前调用所有互斥对象(使用 std::lock_guard(,以避免线程冲突。我的第一个想法是使用 for 循环来做到这一点:

for(int i = 0; i < number_of_mutex; i++)
std::lock_guard<std::mutex> mut[i];

当然,这不起作用,因为每次迭代后lock_guards都会超出范围。因此,我决定创建一个外部向量来存储lock_guards:

std::vector<std::lock_guard<std::mutex>> mut_set;
for(int i = 0; i < number_of_mutex; i++)
mut_set.push_back(std::lock_guard<std::mutex>(mut[i]));

我的程序现在可以编译,但我怀疑这可能不正确。控制台显示"错误:使用已删除的功能":

/home/main.cpp:2162:74:   required from here
/usr/include/c++/7/ext/new_allocator.h:136:4: error: use of deleted function ‘std::lock_guard<_Mutex>::lock_guard(const std::lock_guard<_Mutex>&) [with _Mutex = std::mutex]’
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }

请注意,lock_guards是不可复制的。 这种情况应该如何正确解决?

std::lock_guard既不可复制也不可移动,因为您通常希望使用它来锁定范围。因此,如果您可以以某种方式使其离开其范围(这将通过将其传递给向量来发生(,那就太糟糕了。这没有,因为std::vector需要其元素类型是可移动或可复制的(因此它可以重新分配/调整大小等(。

您可以改用std::unique_lock.但请注意,当线程已经拥有互斥锁时,不会发生任何坏事(请参阅其构造函数的页面(。

正如 Sam 已经说过的那样,另一种可能性是添加另一个级别的间接寻址并使用存储在矢量中的一些智能指针(unique_ptr也应该工作,我更喜欢它(来管理lock_guards。

但我同意山姆所说的话:重新考虑你的设计。