有ConnectionManager
等待传入连接。对于每个传入连接,它会创建一个Connection
实例,用于处理此连接上的入站和出站流量。每个Connection
都有Watchdog
处理“错误连接”条件,并调用已注册的“Listerners”。一个“监听器”是ConnectionManager
,它关闭连接并删除Connection
实例,后者又删除相应的看门狗。
等待。 A.分钟。
Watchdog
调用ConnectionManager
删除删除Connection
的{{1}}?看门狗追逐自己的尾巴。
我完全被封锁了。我该如何解决这个问题?
解决方案:我会使Listener异步,尽管我还不知道如何在没有太多痛苦的情况下做到这一点。 Watchdog
不了解Watchdog
。这是相当通用的。此外,Win32-Thread-API没有类似“join”的内容,因此我可能需要使用ConnectionManager
和GetExitCodeThread()
来推送自己的...
谢谢,伙计们。
答案 0 :(得分:3)
信息。
不是让Watchdog调用ConnectionManager
的方法,而是将消息发布到连接管理器中的队列。此队列需要是线程安全的。当ConnectionManager
在其线程中处理队列时,等待Connection线程结束是安全的。
Watchdog Queue ConnectionManager
| | |
Kill Connection---->| |
| |<-------------------Get Message
--- | |
|-------------------->Process Message
| |
| Kill Connection
答案 1 :(得分:2)
如果这些对象中的每一个都在自己的线程中运行,则没有问题。
Watchdog通知ConnectionManager并返回 此时Watchdog线程可以退出。
当ConnectionManager注意到监视程序事件时,它会终止连接线程。
答案 2 :(得分:2)
如果监视程序在另一个线程中运行,那么问题也不会太糟糕 - 监视程序通过异步消息通知ConnectionManager删除,然后退出它自己的线程。
同时,ConnectionManager线程获取删除消息,并开始删除监视程序。
为了避免竞争条件,看门狗析构函数应该加入监视程序线程,并清理线程。 (可能还会发出监视器线程的信号,或断言()有关看门狗线程准备退出的事情。)
答案 3 :(得分:0)
如果你小心,没有问题。
ConnectionInstance :: a_method()调用Watchdog :: a_method()调用ConnectionManager :: a_method
ConnectionManager :: a_method()删除ConnectionInstance删除Watchdog
ConnectionManager :: a_method()返回Watchdog :: a_method()返回ConnectionInstance :: a_method()。只要返回路径不访问任何成员,它只是从函数返回。标准仍然存在代码,因此您可以放心地返回。
这需要仔细编码和维护,但它看起来并不是一个肮脏的黑客。
异步协议需要相同的思考。这不仅仅是因为你需要避免Watchdog在ConnectionManager ::队列中请求删除和ConnectionManager同时对队列执行某些操作。问题更深层:有一段时间ConnectionInstance不起作用 - 它已请求删除 - 但仍未删除。它在做什么?代码不能保持不变。如果对于未解散的ConnectionInstance有一个安全的出路,你也可以自己回滚堆栈,而不需要创建额外的异步协议。
看起来抛出异常可能是处理ConnectionInstance的一种更简单的方法,如果它们在同一个线程中。