【问题标题】:C++ boost thread causes segmentation fault when instantiated twiceC++ boost线程在实例化两次时导致分段错误
【发布时间】:2017-05-04 15:08:47
【问题描述】:

我有一个在构造时运行后台任务的类(请参阅构造函数)。然后停止此任务,并在对象被销毁时将线程加入析构函数中:

// Foo.hpp -------------------------------
#include <boost/thread.hpp>
#include <boost/date_time/posix_time.hpp>

class Foo {
  boost::thread theThread;

  Foo();
  ~Foo();
  void bar() const;
}

// Foo.cpp -------------------------------
// This is the background task.
void Foo::bar() const {
  while (true) {
    try {
      // sleep for 1 minute.
      boost:this_thread_sleep(boost::posix_time::minutes(1));

      // do other stuff endlessly
    }

    // boost interrupt was called, stop the main loop.
    catch (const boost::thread_interrupted&)
    {
      break;
    }
}

// Instantiate background task
Foo::Foo()
    : theThread(&Foo::bar, this)
{
    // do other stuff
}

// Stop background task
Foo::~Foo() {
    theThread.interrupt()
    theThread.join();
}

现在,当我有一个类的单个实例时,这可以正常工作:

// main.cpp
Foo f;
// do other stuff with f

但是当我这样做时,我得到一个分段错误和一个中止的消息:

// main.cpp
Foo *f;
f = new Foo(); // causes seg fault
delete f;

为什么?

【问题讨论】:

  • boost::thread 是否尝试取消引用其构造函数中的第二个参数(在您的情况下为 this)?如果是这样,那么在初始化列表中使用this 作为参数似乎并不安全。
  • 不确定是否在将 foo::bar 提供给线程时构建了它
  • 抱歉,您的代码无法编译,并且您的析构函数是私有的,因此您无法在 main.cpp 中实例化此类。您确定此代码重现了您的问题吗?

标签: c++ multithreading boost


【解决方案1】:

Xcode 报错:

尝试使用已删除的函数

Foo::Bar 不能用上面的语法调用(&Foo::Bar),因为它不是一个静态函数。它有一个隐藏的这个参数,导致签名不匹配。

更多信息在这里: pthread function from a class

在初始化列表上使用成员函数也是不好的做法,行为是未定义的。在此引用:

可以调用成员函数(包括虚成员函数) 来自成员初始值设定项,但行为未定义(如果不是全部) 直接基在此时初始化。

http://en.cppreference.com/w/cpp/language/initializer_list

以下作品:

   void bar(atomic_int*exit) {
    while (*exit) {
        // sleep for 1 minute.
        this_thread::sleep_for(std::chrono::seconds(2));

        // do other stuff endlessly

    }
}

class Foo {
    thread theThread;
    atomic_int _exit;

public:
   // Instantiate background task
    Foo(): _exit(1)
    {
        // do other stuff
        init();
    }
    void init()
    {
        theThread = std::thread (&bar,&_exit);
    }

    // Stop background task
    ~Foo() {
        _exit = 0;
        theThread.join();
    }
};

【讨论】:

  • 我的 c++ 版本中没有 std::thread 或 atomic 类型,对不起,兄弟,不起作用。
  • 抱歉,我不使用 boost,但如果您想进一步了解,它确实有 boost::atomic。在任何情况下,您都不能以这种方式传递成员函数,需要将其外部化或使其成为静态。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-11
  • 2021-12-13
  • 1970-01-01
  • 2013-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多