C++ boost线程在实例化两次时导致分段错误
Posted
技术标签:
【中文标题】C++ boost线程在实例化两次时导致分段错误【英文标题】:C++ boost thread causes segmentation fault when instantiated twice 【发布时间】: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 中实例化此类。您确定此代码重现了您的问题吗?
【参考方案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以上是关于C++ boost线程在实例化两次时导致分段错误的主要内容,如果未能解决你的问题,请参考以下文章