我在活动主题中有一个通知中心:
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
编辑的工作线程可能会在销毁之后被访问。
我的问题是:这是一个有效的问题,如果是这样,我该怎么做才能确保在return
之后不会发出通知?
答案 0 :(得分:1)
编辑:由于menu
是disabling被删除的观察者,因此上述代码是安全的。下面的答案留给记录以理解评论部分。
原始答案:
这是一个有效的问题 - 工作线程函数可以在add / removeObserver()调用之间被抢占。由于所有观察者指针的enter code here
SELECT * FROM Table1
INNER JOIN Table2 ON Table1.user_id = Table2.user_id
INNER JOIN Table3 ON Table2.[phone no] = Table3.[phone no]
makes a copy *,如果有来自其他线程的多个通知,则在调用{{{{{{{{{{{{{{{{{ 1}}(甚至在函数返回后)。
现在,无需担心函数返回后被访问的观察者,因为NotificationCenter将cloned SharedPtr放入naked address。但是,有一个问题是当时正在调用通知处理程序,因为NObserver持有disarm。为了防止发生错误,请在从函数返回之前调用removeObserver()
- 这将{{3}}以线程安全的方式处理任何待处理通知的通知。
* 出于性能原因 - 我们不希望在所有通知处理程序正在执行时阻止其余的NotificationCenter。