3

我在 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 !!!
}

提前感谢任何提示或方向,

-埃德

4

1 回答 1

2

如果你真的必须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;
}

发送给订阅者的共享参数对象将在其引用计数变为零时自动删除(即超出所有处理程序的范围)。

Parameter 真的那么重,需要通过指针发送给订阅者吗?

编辑:

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

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

于 2010-01-10T22:04:57.087 回答