*** 作结束时的代码大致如下:
_opEndedMutex.lock();_thereIsOngoingOp = false;_opEndedCondition.notify_all();_opEndedMutex.unlock();//no more call after notificationm_spnotificationmanager->OperationEnded();
而wait()函数如下:
boost::unique_lock<boost::mutex> lock(_opEndedMutex);while(_thereIsOngoingOp){ _opEndedCondition.wait(_opEndedMutex);}
问题在于资源管理.这是一个C类,因此当检测到 *** 作结束时,此类的用户可能会删除 *** 作符对象(如果有任何活动 *** 作,析构函数将等待完成).可以通过等待或接受通知来检测 *** 作的结束.因此,如果我首先调用_opEndedCondition.notify_all()并且用户删除 *** 作符对象,则在尝试调用OperationEnded()时可能会崩溃,因为m_spnotificationmanager已被删除.如果选择首先调用OperationEnded()并且用户在此调用期间删除 *** 作符对象,则在尝试访问_opEndedMutex,_thereIsOngoingOp和_opEndedCondition时可能会崩溃.
我想到的第一件事就是使用新的互斥锁来保护这两个调用.这看起来并不漂亮,因为我无法预见如果引入新的互斥锁会发生什么,并且如果在OperationEnded()通知中用户同步启动新 *** 作.我也不确定如何在wait()方法中使用新的互斥锁.
注1:此API用于我们自己公司和其他公司的应用程序.所以我无法摆脱任何一种同步机制.
注意2:我修改了原始代码,变量和方法名称,因此可能存在拼写错误,但这个想法应该是明确的.
EDIT1:
运算符对象保留在通过工厂生成的共享库中,然后通过接口暴露给外部世界.
所以 *** 作符对象的典型生命周期如下:
IOperator * op = factory:getNewOperator();//perform operations with opop->Release() //this one goes and deletes the op object
另请注意,运算符对象是可重用的.客户端代码可以使新的 *** 作符对象多次使用它并在最后删除它.
解决方法 你有几个解决方案:>您可以从std::enable_shared_from_this专门化您的 *** 作对象.这意味着在客户端代码中,您不再删除该对象,而是将std :: shared_ptr设置为nullptr,并且在实际删除对象时不关心.
>您可以在计时器延迟时实现有限的垃圾收集:当您在客户端代码中收到OperationEnded()通知时,您将获取指针并将其放在队列中,以及添加对象时的时间戳.然后队列将有一个活动对象在计时器上唤醒,占用当前时间,如果时间戳(比如说)比当前时间至少早五秒,则删除它.
>您可以使用object pool分配和取消分配 *** 作类.当不再使用某个对象时,它实际上不会被删除,而是作为池中的免费(回收)对象放置.在完成处理后,当池被销毁时,实际上将删除该对象.>您可以为对象创建生命周期管理器,这将删除您的 *** 作对象,然后发送通知.>你可以让’OperationEnded’函数调用删除这个;在末尾;然后,您将实现客户端代码,以便在接收通知时将指针设置为NulL;这样的解决方案虽然很脆弱,但实际上,这可能会将问题转移到另一段代码中.>最后,您可以实现所有这些的自定义组合.
以上是内存溢出为你收集整理的c – 我应该以哪种顺序发送callback()并通知服务员?全部内容,希望文章能够帮你解决c – 我应该以哪种顺序发送callback()并通知服务员?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)