【问题标题】:Possibility of segmentation fault with mutex in class with multithreading多线程类中的互斥体可能出现分段错误
【发布时间】:2023-03-26 02:20:01
【问题描述】:

多个线程 (std::async) 通过shared_ptr 共享以下类的实例,是否可能在这部分代码中出现分段错误?如果我对std::mutex 的理解是正确的,mutex.lock() 会导致所有其他试图调用mutex.lock() 的线程阻塞,直到调用mutex.unlock(),因此对向量的访问应该完全按顺序进行。我在这里错过了什么吗?如果没有,是否有更好的方法来设计这样的类(可能使用std::atomic_flag)?

#include <mutex>
#include <vector>
class Foo
{
   private:
      std::mutex mutex;
      std::vector<int> values;
   public:
      Foo();
      void add(const int);
      int get();
};
Foo::Foo() : mutex(), values() {}
void Foo::add(const int value)
{
   mutex.lock();
   values.push_back(value);
   mutex.unlock();
}
int Foo::get()
{
   mutex.lock();
   int value;
   if ( values.size() > 0 )
   {
      value = values.back();
      values.pop_back();
   }
   else
   {
      value = 0;
   }
   mutex.unlock();
   return value;
}

免责声明:get() 中的默认值 0 是因为它在其余代码中具有特殊含义。

更新:上面的代码与我使用的完全一样,当然除了拼写错误 push_Back。

【问题讨论】:

  • 段错误在哪里?
  • 我看不出这个类有什么问题,但你应该使用lock_guard&lt;&gt;unique_lock&lt;&gt; 来获取互斥体,并在RAII 包装器超出范围时自动释放。您是否显示了整个类定义?
  • 另外,除了同时访问它们之外,你对这个类的对象做了什么?你在抄袭吗?
  • 更新问题。 @AndyProwl:这个类只有一个对象,shared_ptr 只是为了在开发的早期阶段提供方便。 @hmjd:是的,除了这样的错别字,谢谢
  • @stefan:你能显示客户端代码吗?

标签: c++ c++11 thread-safety segmentation-fault mutex


【解决方案1】:

除了不使用 RAII 获取锁并使用 size() &gt; 0 而不是 !empty() 之外,代码看起来还不错。这正是互斥锁的使用方式,这是您需要互斥锁的方式和位置的典型示例。

正如 Andy Prowl 所指出的,实例不能被复制构造或复制分配。

【讨论】:

  • 如果有人滥用接口,这将导致编译时错误。 无论如何它都不会编译,因为将std::mutex 作为成员会阻止生成默认的复制构造函数和赋值运算符。
【解决方案2】:

这是“改进”版本:

#include <mutex>
#include <vector>
class Foo {
   private:
      std::mutex mutex;
      typedef std::lock_guard<std::mutex> lock;
      std::vector<int> values;
   public:
      Foo();
      void add(int);
      int get();
};
Foo::Foo() : mutex(), values() {}
void Foo::add(int value) {
   lock _(mutex);
   values.push_back(value);
}
int Foo::get() {
   lock _(mutex);
   int value = 0;
   if ( !values.empty() )
   {
      value = values.back();
      values.pop_back();
   }
   return value;
}

使用 RAII 获取mutex 等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-27
    • 2021-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-25
    • 2011-07-15
    • 2011-08-25
    相关资源
    最近更新 更多