在一个函数中创建多个lock_guards

我有一个类,其中包含一个向量,该向量充满了指向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是不可复制的。 这种情况应如何正确解决?

Hnixy 回答:在一个函数中创建多个lock_guards

std::lock_guard类出于充分的理由既不是可复制也不是可移动的,因为您通常希望使用它来锁定作用域。因此,如果您能够以某种方式使其脱离范围(将其传递给向量会发生),那将是不好的。并没有解决这个问题,因为std::vector需要其元素类型是可移动或可复制的(以便它可以重新分配/调整大小等)

您可以改为使用std::unique_lock。但是请注意,当线程已经拥有互斥体时,不会发生任何不良情况(请参见其构造函数上的页面)。

就像Sam所说的那样,另一种可能性是添加另一个间接级别,并使用存储在向量中的一些智能指针(unique_ptr也应该起作用,我更喜欢)来管理lock_guards。

但是我同意Sam所说的:重新考虑您的设计。

本文链接:https://www.f2er.com/2708171.html

大家都在问