gpt4 book ai didi

c++ - Poco - 安全地使用 removeObserver

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:17:00 27 4
gpt4 key购买 nike

我在事件线程中有一个通知中心:

Poco::NotificationCentre nc;   // publicly visible

// (thread main loop which will post notifications from time to time)

还有多个工作线程对通知进行操作。然而,那些等待通知的线程也可能需要在任何时候从外部发出退出信号。所以我在我的工作线程中得到了以下内容(同样,为了清楚起见,这是伪代码,省略了一些细节)

Poco::Event event;
std::string s;
MyNotificationClass notifier{event, s}; // holds those by reference
Poco::NObserver<MyNotificationClass, MyNotification> obs(notifier, &MyNoficationClass::func);

nc.addObserver(obs);
event.wait();
nc.removeObserver(obs);

return s;

通知类是:

struct MyNotificationClass
{
MyNotificationClass(Poco::Event &ev, std::string &s): ev(ev), s(s) {}
void func(const Poco::AutoPtr<MyNotification> &p)
{
s = p->s;
ev.set();
}
Poco::Event &ev;
std::string &s;
};

我担心的是,即使在工作线程中调用了 removeObserver 之后,通知中心也可能同时收到通知,所以对象 s 在工作线程刚从中返回的函数中,在它被销毁后可能会被访问​​。

我的问题是:这是一个有效的问题吗?如果是,我应该怎么做才能确保在 return 之后不会发生通知?

最佳答案

编辑:因为removeObserver()disabling被移除的观察者,上面的代码是安全的。下面的答案留作记录以便理解评论部分。


原答案:

这是一个有效的问题 - 工作线程函数可以在 add/removeObserver() 调用之间被抢占。自 postNotification() makes a copy * 在所有观察者的指针中,如果有来自其他线程的多个通知,在您调用 removeObserver() (甚至函数返回后)。

现在,不必担心函数返回后会访问观察者,因为它是cloned。进入 SharedPtr由通知中心。但是,由于 NObserver 持有其 naked address,因此此时调用通知处理程序令人担忧。 .为了防止坏事发生,在从函数返回之前调用 obs.disable() - 这将 disarm以线程安全的方式处理任何未决通知。


* 出于性能原因 - 我们不想在所有通知处理程序执行时阻塞 NotificationCenter 的其余部分。

关于c++ - Poco - 安全地使用 removeObserver,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32195463/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com