代码之家  ›  专栏  ›  技术社区  ›  EricSchaefer

穿线问题(追尾)

  •  1
  • EricSchaefer  · 技术社区  · 16 年前

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

    等待。A分钟。

    这个 看门狗 调用 连接管理器 它删除了 连接 它删除了 看门狗 ?看门狗追赶自己的尾巴。

    我完全被封锁了。如何解决此问题?


    解决方案 我会让听者感觉像异步的,尽管我还不知道如何在不太痛苦的情况下做到这一点。这个 看门狗 不知道 连接管理器 . 它相当通用。另外,Win32线程API没有类似“join”的内容,因此我可能需要使用 GetExitCodeThread() STILL_ACTIVE

    谢谢,伙计们。

    4 回复  |  直到 12 年前
        1
  •  2
  •   Douglas Leeder    16 年前

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

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

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

        2
  •  3
  •   Tim Cooper    12 年前

    消息传递。

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

    Watchdog          Queue               ConnectionManager
       |                |                        |
    Kill Connection---->|                        |
       |                |<-------------------Get Message
      ---               |                        |
                        |-------------------->Process Message
                        |                        |
                        |                     Kill Connection
    
        3
  •  2
  •   Loki Astari    16 年前

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

    监视程序通知ConnectionManager并返回。
    此时,看门狗线程就可以退出了。

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

        4
  •  0
  •   n-alexander    16 年前

    如果你细心的话,没有问题。

    1. ConnectionInstance::a_method()调用看门狗::a_method()调用ConnectionManager::a_方法

    2. ConnectionManager::a_method()删除ConnectionInstance删除看门狗

    3. ConnectionManager::a_method()返回看门狗::a_method()返回ConnectionInstance::a_method()。只要返回路径不访问任何成员,它只是一个函数的返回。按照标准,代码仍然存在,因此您可以安全地返回。

    这需要仔细的编码和维护,但这似乎不是一个肮脏的黑客。

    异步协议需要同样的思考。不仅如此,您还需要避免在ConnectionManager::Queue中的看门狗请求删除与同时处理队列的ConnectionManager之间出现竞争。问题更严重:有一段时间,ConnectionInstance无法正常工作-它已请求删除-但尚未删除。它在做什么?代码不能保持不变。如果有一个安全的方法可以解决不失效的连接实例,那么您也可以自己回滚堆栈,而不创建额外的异步协议。

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