代码之家  ›  专栏  ›  技术社区  ›  Ed of the Mountain

增强信号-如何控制发送给用户的对象的生存期?智能指针?

  •  3
  • Ed of the Mountain  · 技术社区  · 14 年前

    我在Red Hat Enterprise Linux 5.3下使用boost::signals2。

    我的信号创建一个对象副本并将其指针发送给订阅服务器。这是为了线程安全而实现的,以防止工作线程在读取对象的同时更新对象的字符串属性(也许我应该重新使用锁?).

    无论如何,我关心的是多个订阅服务器在自己的线程上取消引用指向复制对象的指针。如何控制对象生存期?我如何知道所有订阅服务器都已完成对该对象的操作,并且删除该对象是安全的?

    typedef boost::signals2::signal< void ( Parameter* ) > signalParameterChanged_t;
    signalParameterChanged_t    m_signalParameterChanged;
    
    // Worker Thread - Raises the signal
    void Parameter::raiseParameterChangedSignal()
    {
          Parameter* pParameterDeepCopied = new Parameter(*this);
          m_signalParameterChanged(pParameterDeepCopied);
    }
    // Read-Only Subscriber Thread(s) - GUI (and Event Logging thread ) handles signal
    void ClientGui::onDeviceParameterChangedHandler( Parameter* pParameter)
    {
          cout << pParameter->toString() << endl;
          delete pParameter;  // **** This only works for a single subscriber !!!
    }
    

    提前感谢您提供任何提示或指导,

    -ED

    1 回复  |  直到 14 年前
        1
  •  2
  •   Emile Cormier    14 年前

    如果你真的要通过 Parameter 通过指向订阅服务器的指针,您应该使用 boost::shared_ptr :

    typedef boost::shared_ptr<Parameter> SharedParameterPtr;
    typedef boost::signals2::signal< void ( SharedParameterPtr ) > signalParameterChanged_t;
    signalParameterChanged_t    m_signalParameterChanged;
    
    // The signal source
    void Parameter::raiseParameterChangedSignal()
    {
          SharedParameterPtr pParameterDeepCopied = new Parameter(*this);
          m_signalParameterChanged(pParameterDeepCopied);
    }
    // The subscriber's handler
    void ClientGui::onDeviceParameterChangedHandler( SharedParameterPtr pParameter)
    {
          cout << pParameter->toString() << endl;
    }
    

    发送到订阅服务器的共享参数对象将在其引用计数为零时自动删除(即,它超出了所有处理程序的范围)。

    参数是否真的很重以至于您需要通过指针将其发送给订户?

    编辑:

    请注意,使用shared_ptr负责生命周期管理,但不会免除您对共享参数对象线程进行并发读/写的责任。出于线程安全的原因,您很可能希望将副本传递给订阅服务器。在你的问题中,我不太清楚什么是线状的,所以我不能给你更具体的建议。

    线程正在调用吗 raiseParameterChangedSignal() 与您的GUI线程相同?一些GUI工具包不允许多个线程同时使用它们的API。