【问题标题】:Named pipes: Many clients. How to be prudent with thread creation? Thread Pool?命名管道:许多客户端。如何谨慎创建线程?线程池?
【发布时间】:2011-03-28 19:03:08
【问题描述】:

情况:

我正在使用 C++ 在 Windows 上为 IPC 使用命名管道。

服务器通过 CreateNamedPipe 创建命名管道实例,并等待客户端通过 ConnectNamedPipe 连接。

每次客户端调用 CreateFile 来访问命名管道时,服务器都会使用 CreateThread 创建一个线程来为该客户端提供服务。之后,服务器重复循环,通过 CreateNamedPipe 创建一个管道实例并通过 ConnectNamedPipe 监听下一个客户端,等等......

问题:

每个客户端请求都会在服务器上触发一个 CreateThread。如果客户来得又快又猛,就会有很多对 CreateThread 的调用。

问题:

Q1:是否可以重用已经创建的线程来服务未来的客户端请求? 如果可以,我应该怎么做?

Q2:线程池在这种情况下会有帮助吗?

【问题讨论】:

    标签: multithreading winapi ipc named-pipes threadpool


    【解决方案1】:

    在 Windows 上,构建并发服务器的最有效方法是使用带有完成端口的异步模型。但是是的,您也可以使用线程池并使用阻塞 i/o,因为这是一种更简单的编程抽象。

    Vista/Windows 2008 提供线程池抽象。

    【讨论】:

    • 感谢您的推荐 - I/O 完成端口看起来很有希望。我会阅读更多关于它的信息。 (我的目标是 XP 及以上)。
    【解决方案2】:

    我今天使用 IOCompletion 端口编写了一个命名管道服务器,只是为了看看如何。

    基本的逻辑流程是:

    • 我通过 CreateNamedPipe 创建了第一个命名管道
    • 我使用该句柄创建了主 Io 完成端口对象:CreateIoCompletionPort
    • 我创建了一个工作线程池 - CPU x2。每个工作线程循环调用 GetQueuedCompletionStatus。
    • 然后调用 ConnectNamedPipe,传入一个重叠结构。当此管道连接时,GetQueuedCompletionStatus 调用之一将返回。
    • 然后,我的主线程通过调用 GetQueuedCompletionStatus 加入工作人员池。

    真的是这样。

    每次线程从 GetQueuedCompletionStatus 返回时,都是因为关联的管道已连接、已读取数据或已关闭。 每次连接管道时,我立即创建一个未连接的管道来接受下一个客户端(一次可能有多个等待)并在当前管道上调用 ReadFile,传递一个重叠的结构 - 确保数据到达时 GetQueuedCompletionStatus 将告诉我吧。

    有几个恼人的边缘情况,函数返回失败代码,但 GetLastError() 是成功的。因为函数“失败”,您必须立即处理成功,因为没有发布排队完成状态。相反,(我相信 Vista 添加了一个 API 来“修复”这个问题)如果数据立即可用,重叠的函数可以返回成功,但也会发布排队完成状态,因此请注意不要在这种情况下重复处理数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-21
      • 1970-01-01
      • 1970-01-01
      • 2023-02-11
      • 1970-01-01
      • 2012-08-27
      • 2010-10-17
      • 1970-01-01
      相关资源
      最近更新 更多