c++ - 在一个函数中创建多个lock_guards

标签 c++ multithreading thread-safety locking mutex

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

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

当然,这是行不通的,因为每次迭代后lock_guards超出范围。因此,我决定创建一个外部 vector 来存储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类出于充分的理由既不是可复制也不是可移动的,因为您通常希望使用它来锁定作用域。因此,如果您能够以某种方式使其脱离范围(将其传递给 vector 会发生),那将是不好的。由于std::vector要求其元素类型是可移动或可复制的(因此它可以重新分配/调整大小等),因此没有任何解决方法。

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

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

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

关于c++ - 在一个函数中创建多个lock_guards,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59924273/

相关文章:

java - 使用 Apache Commons Exec 运行进程时从控制台获取所有输出数据

c++ - LibAv/FFMpeg 的线程安全性?

c - OS X 上 C 标准库的线程安全

c++ - 将 8 个字符从内存加载到 __m256 变量中作为打包的单精度 float

c++ - 具有周期性边界条件的连通分量

c++ - 如何在winapi中创建字符串数组

java - 使用多线程同时向 Kafka 分区发布多条消息以进行测试以检查性能

c++ - PostMessage 和 AfxBeginThread 有什么区别?

iOS 更改 UI 时,我应该从主线程调用什么?

c++ - 如何正确格式化此表?