【问题标题】:shared_from_this() from another thread (a member thread function)shared_from_this() 来自另一个线程(成员线程函数)
【发布时间】:2011-06-13 09:26:47
【问题描述】:

在我的代码中,我使用 boost::threads 并且我有一个类通过名为 fnThread() 的成员函数运行线程。在这个 fnThread() 中,我想创建一个 shared_from_this() 并将其传递给带有信号的监听方。但是boost::shared_ptr<foo> p = 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 并且我想听听任何关于这个决定的 cmets。对于这种特殊情况,也许这是一个糟糕的选择。你有什么建议?

编辑:

这里有一个简单的类供你测试

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;
    }
};

【问题讨论】:

  • 你是什么意思,“创建一个shared_from_this()?”
  • 我的意思是让 'boost::shared_ptr' 变成 'this'
  • 请向我们展示实例化foo 并调用start 的代码。错误可能就在那里。
  • 我找到了错误的根源。在一个函数中,我从一个双端队列“弹出”对象并调用它的 start 方法。一旦函数返回,该对象的唯一实例就会超出范围,但线程会继续运行并在尝试获取“shared_from_this()”时崩溃。愚蠢的错误......

标签: c++ multithreading shared-ptr boost-thread


【解决方案1】:

shared_from_this 可以在另一个线程中使用。当不存在shared_ptrthis(顾名思义)时,会抛出bad_weak_ptr 异常。您的问题很可能存在于代码的其他地方。

【讨论】:

  • 如何同时从多个线程对一个对象调用shared_from_this
【解决方案2】:

正如@Sam Miller 已经提到的,问题存在于其他地方。我可以想象您将foo 声明为scoped_ptr&lt;foo&gt;。通过这样做,shared_from_this 不可能返回有效的共享指针,因为 boost::scoped_ptr 类型的智能指针无法转移对象的所有权。这是您异常的原因。

【讨论】:

    【解决方案3】:

    您可以考虑将boost::shared_ptr&lt;&gt; 更改为boost::intrusive_ptr&lt;&gt;。主要区别在于boost::intrusive_ptr&lt;&gt; 建议将引用计数器存储在对象内部(尽管可以将其存储在其他地方)。使用嵌入式引用计数器,您可以在构造函数中从 this 构造一个 boost::intrusive_ptr&lt;&gt;,也可以随时从普通指针构造一个 boost::intrusive_ptr&lt;&gt;(但不要在析构函数中从 this 获取 boost::intrusive_ptr&lt;&gt;)。

    【讨论】:

      【解决方案4】:

      shared_from_this()不能在构造函数完成之前调用,也不能在析构函数启动之后调用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-27
        • 1970-01-01
        相关资源
        最近更新 更多