c – 我应该以哪种顺序发送callback()并通知服务员?

前端之家收集整理的这篇文章主要介绍了c – 我应该以哪种顺序发送callback()并通知服务员?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个类,通过它我可以异步提供一些服务(同样的调用也可以同步进行).当请求时,此类的对象(比如运算符)在另一个线程中启动操作.其他对象可以注册到操作符对象的通知,以便在操作结束时对此对象调用OperationEnded()方法.其他对象也可以通过调用操作符对象上的Wait()来等待此操作的完成.

操作结束时的代码大致如下:

_opEndedMutex.lock();
_thereIsOngoingOp = false;
_opEndedCondition.notify_all();
_opEndedMutex.unlock();

//no more call after notification
m_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:

运算符对象保留在通过工厂生成的共享库中,然后通过接口暴露给外部世界.@H_301_21@所以操作符对象的典型生命周期如下:

IOperator * op = factory:getNewOperator();
//perform operations with op
op->Release() //this one goes and deletes the op object

另请注意,运算符对象是可重用的.客户端代码可以使新的操作符对象多次使用它并在最后删除它.

解决方法

你有几个解决方案:

>您可以从std::enable_shared_from_this专门化您的操作对象.这意味着在客户端代码中,您不再删除该对象,而是将std :: shared_ptr设置为nullptr,并且在实际删除对象时不关心.@H_301_21@>您可以在计时器延迟时实现有限的垃圾收集:当您在客户端代码中收到OperationEnded()通知时,您将获取指针并将其放在队列中,以及添加对象时的时间戳.然后队列将有一个活动对象在计时器上唤醒,占用当前时间,如果时间戳(比如说)比当前时间至少早五秒,则删除它.@H_301_21@>您可以使用object pool分配和取消分配操作类.当不再使用某个对象时,它实际上不会被删除,而是作为池中的免费(回收)对象放置.在完成处理后,当池被销毁时,实际上将删除该对象.>您可以为对象创建生命周期管理器,这将删除您的操作对象,然后发送通知.>你可以让’OperationEnded’函数调用删除这个;在末尾;然后,您将实现客户端代码,以便在接收通知时将指针设置为NULL;这样的解决方案虽然很脆弱,但实际上,这可能会将问题转移到另一段代码中.>最后,您可以实现所有这些的自定义组合.

猜你在找的C&C++相关文章