2011-01-21 134 views
2

在我的代码中,我使用boost::threads,我有一个类通过一个称为fnThread()的成员函数运行线程。在这个fnThread()中我想创建一个shared_from_this()并将它传递给有信号的收听方。但行boost::shared_ptr<foo> p = shared_from_this()抛出一个异常如下;shared_from_this()从另一个线程(一个成员线程函数)

boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_weak_ptr> > at memory location 0x04c2f720. 

有问题的命令是shared_from_this()。从另一个线索创建shared_from_this()是否违法或我做错了什么?任何帮助表示赞赏。谢谢 ! PS:我计划改变我的信号参数为普通指针,因为它不会影响我的结构。但我赞成shared_ptr <>,我想听取有关该决定的任何意见。也许这对于这种特殊情况是一个不好的选择。你有什么建议?

编辑:

下面是一个简单的类,以测试

class foo : public boost::enable_shared_from_this<foo> 
{ 
public: 
    int start() 
    { 
     foo_thread.reset(new boost::thread(boost::bind(&foo::fn_foo_thread, this))); 

     return 0; 
    } 

    ~foo() 
    { 
     if (foo_thread->joinable()) 
      foo_thread->join(); 
    } 

private: 
    boost::scoped_ptr<boost::thread> foo_thread; 

    void fn_foo_thread() 
    { 
     boost::shared_ptr<foo> p = shared_from_this(); 
     std::cout << "foo thread terminated. \n" << std::endl; 
    } 
}; 
+0

你是什么意思,“创建'shared_from_this()'?” –

+0

我的意思是将'boost :: shared_ptr '改为'this' – fgungor

+1

请向我们展示实例化'foo'并调用'start'的代码。错误可能在那里。 – Macke

回答

0

你可能要考虑改变boost::shared_ptr<>boost::intrusive_ptr<>。主要区别在于boost::intrusive_ptr<>表明引用计数器存储在对象内部(尽管可以将其存储在其他地方)。使用嵌入式引用计数器,您可以根据需要在构造函数或纯指针中构造一个boost::intrusive_ptr<>(但不要在析构函数中使用boost::intrusive_ptr<>)。

4

shared_from_this可以从其他线程使用。当不存在shared_ptrthis(顾名思义)时引发bad_weak_ptr异常。您的问题很可能存在于代码中的其他地方。

+0

怎么样从多个线程同时调用一个对象上的'shared_from_this'? – updogliu

+1

'shared_from_this'是线程安全的。 –

2

正如@Sam Miller所提到的,这个问题在其他地方存在。我可以想象你宣布foo是一个scoped_ptr<foo>。通过这样做,shared_from_this不可能返回有效的共享指针,因为boost::scoped_ptr类型的智能指针不能传输对象的所有权。这里是你例外的原因。

0

shared_from_this()无法在构造函数完成之前或在析构函数启动之后调用。