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

时间:2008-12-08 13:25:38

标签: c++ multithreading

ConnectionManager等待传入连接。对于每个传入连接,它会创建一个Connection实例,用于处理此连接上的入站和出站流量。每个Connection都有Watchdog处理“错误连接”条件,并调用已注册的“Listerners”。一个“监听器”是ConnectionManager,它关闭连接并删除Connection实例,后者又删除相应的看门狗。

等待。 A.分钟。

Watchdog调用ConnectionManager删除删除Connection的{​​{1}}?看门狗追逐自己的尾巴。

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


解决方案:我会使Listener异步,尽管我还不知道如何在没有太多痛苦的情况下做到这一点。 Watchdog不了解Watchdog。这是相当通用的。此外,Win32-Thread-API没有类似“join”的内容,因此我可能需要使用ConnectionManagerGetExitCodeThread()来推送自己的...

谢谢,伙计们。

4 个答案:

答案 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)

如果你小心,没有问题。

  1. ConnectionInstance :: a_method()调用Watchdog :: a_method()调用ConnectionManager :: a_method

  2. ConnectionManager :: a_method()删除ConnectionInstance删除Watchdog

  3. ConnectionManager :: a_method()返回Watchdog :: a_method()返回ConnectionInstance :: a_method()。只要返回路径不访问任何成员,它只是从函数返回。标准仍然存在代码,因此您可以放心地返回。

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

    异步协议需要相同的思考。这不仅仅是因为你需要避免Watchdog在ConnectionManager ::队列中请求删除和ConnectionManager同时对队列执行某些操作。问题更深层:有一段时间ConnectionInstance不起作用 - 它已请求删除 - 但仍未删除。它在做什么?代码不能保持不变。如果对于未解散的ConnectionInstance有一个安全的出路,你也可以自己回滚堆栈,而不需要创建额外的异步协议。

    看起来抛出异常可能是处理ConnectionInstance的一种更简单的方法,如果它们在同一个线程中。