增强信号 - 如何控制发送给订阅者的对象的生命周期?智能指针?

发布于 2024-08-17 06:19:21 字数 941 浏览 3 评论 0原文

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

I am using boost::signals2 under Red Hat Enterprise Linux 5.3.

My signal creates an object copy and sends it's pointer to subscribers. This was implemented for thread safety to prevent the worker thread from updating a string property on the object at the same time it is being read ( perhaps I should revisit the use of locks? ).

Anyway, my concern is with multiple subscribers that dereference the pointer to the copied object on their own thread. How can I control object lifetime? How can I know all subscribers are done with the object and it is safe to delete the object?

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

Thanks in advance for any tips or direction,

-Ed

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小傻瓜 2024-08-24 06:19:21

如果您确实必须通过指针将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。

If you really have to pass Parameter by pointer to your subscribers, then you should use 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;
}

The shared parameter object sent to your subscribers will be automatically deleted when its reference count becomes zero (i.e. it goes out of scope in all the handlers).

Is Parameter really so heavyweight that you need to send it to your subscribers via pointer?

EDIT:

Please note that using shared_ptr takes care of lifetime management, but will not relieve you of the responsibility to make concurrent reads/writes to/from the shared parameter object thread-safe. You may well want to pass-by-copy to your subscribers for thread-safety reasons alone. In your question, it's not clear enough to me what goes on thread-wise, so I can't give you more specific recommendations.

Is the thread calling raiseParameterChangedSignal() the same as your GUI thread? Some GUI toolkits don't allow concurrent use of their API by multiple threads.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文