C++ 线程问题(追逐自己的尾巴)

C++ 线程问题(追逐自己的尾巴),c++,multithreading,C++,Multithreading,有ConnectionManager等待传入连接。对于每个传入连接,它创建一个连接实例,用于处理此连接上的入站和出站流量。每个连接都有一个看门狗,它处理“坏连接”情况并调用已注册的“侦听器”。一个“侦听器”是连接管理器,它关闭连接并删除连接实例,然后删除相应的看门狗 等等。一分钟 Watchdog调用ConnectionManager,后者删除连接,后者删除Watchdog?看门狗追逐自己的尾巴 我完全被封锁了。我如何解决这个问题 解决方案:我会让监听器变得异步,尽管我还不知道如何做到这一点而

ConnectionManager
等待传入连接。对于每个传入连接,它创建一个
连接
实例,用于处理此连接上的入站和出站流量。每个
连接
都有一个
看门狗
,它处理“坏连接”情况并调用已注册的“侦听器”。一个“侦听器”是
连接管理器
,它关闭连接并删除
连接
实例,然后删除相应的看门狗

等等。一分钟

Watchdog
调用
ConnectionManager
,后者删除
连接
,后者删除
Watchdog
?看门狗追逐自己的尾巴

我完全被封锁了。我如何解决这个问题


解决方案:我会让监听器变得异步,尽管我还不知道如何做到这一点而不会太痛苦。
看门狗
不知道
连接管理器
。它相当通用。另外,Win32线程API没有类似“join”的功能,因此我可能需要使用
GetExitCodeThread()
仍然处于活动状态的

谢谢,伙计们。

留言

不要让看门狗调用
ConnectionManager
的方法,而是将消息发布到连接管理器中的队列中。此队列必须是线程安全的。当
ConnectionManager
在其线程中处理队列时,可以安全地等待连接线程结束

Watchdog          Queue               ConnectionManager
   |                |                        |
Kill Connection---->|                        |
   |                |<-------------------Get Message
  ---               |                        |
                    |-------------------->Process Message
                    |                        |
                    |                     Kill Connection
看门狗队列连接管理器 | | | 终止连接-->|| ||过程消息 | | |终止连接
信息

不要让看门狗调用
ConnectionManager
的方法,而是将消息发布到连接管理器中的队列中。此队列必须是线程安全的。当
ConnectionManager
在其线程中处理队列时,可以安全地等待连接线程结束

Watchdog          Queue               ConnectionManager
   |                |                        |
Kill Connection---->|                        |
   |                |<-------------------Get Message
  ---               |                        |
                    |-------------------->Process Message
                    |                        |
                    |                     Kill Connection
看门狗队列连接管理器 | | | 终止连接-->|| ||过程消息 | | |终止连接
如果每个对象都在自己的线程中运行,则没有问题

看门狗通知ConnectionManager并返回。
此时,看门狗线程可以退出


当ConnectionManager注意到watchdog事件时,它将终止连接线程。

如果这些对象中的每一个都在其自己的线程中运行,则没有问题

看门狗通知ConnectionManager并返回。
此时,看门狗线程可以退出


当ConnectionManager注意到watchdog事件时,它会终止连接线程。

如果watchdog在另一个线程中运行,那么问题并不太严重-watchdog用异步消息通知ConnectionManager删除,然后退出它自己的线程

同时,ConnectionManager线程获取删除消息,并开始删除看门狗


为了避免竞争条件,看门狗析构函数应该加入看门狗线程,并清理线程。(可能还向看门狗线程发出信号,或者断言()关于看门狗线程准备退出的信息)。

如果看门狗在另一个线程中运行,那么问题并不太严重-看门狗用异步消息向ConnectionManager发出删除的信号,然后退出它自己的线程

同时,ConnectionManager线程获取删除消息,并开始删除看门狗


为了避免竞争条件,看门狗析构函数应该加入看门狗线程,并清理线程。(可能还向看门狗线程发送信号,或断言()看门狗线程准备退出的信息)。

如果您非常小心,则不会出现问题

  • ConnectionInstance::a_方法()调用看门狗::a_方法()调用ConnectionManager::a_方法

  • ConnectionManager::a_method()删除ConnectionInstance删除看门狗

  • ConnectionManager::a_方法()返回到看门狗::a_方法()返回到ConnectionInstance::a_方法()。只要返回路径不访问任何成员,它就只是函数的返回。标准代码仍然存在,因此您可以安全返回

  • 这需要仔细的编码和维护,但它看起来并不是一个肮脏的黑客行为

    异步协议需要同样多的思考。这不仅仅是因为您需要避免在ConnectionManager::queue中请求删除的看门狗和同时处理队列的ConnectionManager之间竞争。问题更深层:有一段时间ConnectionInstance不起作用——它请求删除——但仍然没有删除。它在干什么?代码不能静止不动。如果有一个安全的方法来解决未失效的ConnectionInstance,那么您也可以自己回滚堆栈,而无需创建额外的异步协议


    如果它们在同一个线程中,那么Watchdog抛出异常可能是处理ConnectionInstance的更简单的方法

    如果你很小心,就没有问题了

  • ConnectionInstance::a_方法()调用看门狗::a_方法()调用ConnectionManager::a_方法

  • ConnectionManager::a_method()删除ConnectionInstance删除看门狗

  • ConnectionManager::a_方法()返回到看门狗::a_方法()返回到ConnectionInstance::a_方法()。只要返回路径不访问任何成员,它就只是函数的返回。c