用于小型单线程应用程序的I/O完成端口

I/O Completion Port for small-scale, single-threaded applications?

本文关键字:小型 单线程 应用程序 用于      更新时间:2023-10-16

让我在前面说我从未使用过I/O完成端口,尽管我已经听说它们很多年了。我的背景主要是selectpollepollWSAEventSelectWaitForMulitpleObjects耦合。如果我对以下文本中的I/O完成端口有根本误解,请纠正我的错误。

作为工作项目的一部分,我的任务是开发模拟的插件(DLL),允许客户端连接到插件,并通过TCP向模拟发送/从模拟接收数据。插件充当服务器。该模拟模拟不同(非以太网)接口的通信信道,在这个特定的应用程序中,每个信道有一个套接字是有意义的。我不知道会有多少个客户端,也不知道每个客户端会打开多少个通道(套接字)。然而,我知道完全有可能会有64人以上,而且这不会是一个非常大的数字,最多可能不到1000人。

模拟的一个重要方面是只有当调用其test_cycle函数时,才允许插件工作。在每个测试周期中,我需要:

  1. 接受来自客户端的任何新连接
  2. 从套接字接收数据并将其转发到模拟
  3. 从模拟中接收数据并将其转发给客户端

由于可能有超过64个套接字,我无法(轻松)使用WSAEventSelectWSAWaitForMultipleEvents来检查是否可以读取套接字,或者客户端是否已正常终止连接。

所以我想了另外两种方法可以做到这一点。

  1. 每个插座应无堵塞。每次调用test_cycle时,都会循环遍历所有套接字,试图在每个套接字中接收最大数量的数据。

  2. 使用I/O完成端口并从套接字发出异步接收。在test_cycle中,重复调用GetQueuedCompletionStatusdwMilliseconds参数设置为0,直到指示超时(WAIT_TIMEOUT?)。如果发生接收,请将下一个接收调用推迟到测试周期结束,这样客户端向服务器发送垃圾邮件就不会导致我们在test_cycle中无限循环(希望如此)。

模拟的接口不是线程安全的,将数据转发到模拟的处理工作非常少,所以我认为为I/O完成端口提供工作线程不会有任何好处,因为它只会锁定并调用模拟API。但是,不必轮询每个套接字可能会获得更好的性能。

因此,对于这种规模的应用程序(最大不到1000个套接字,通常不到100个),使用I/O完成端口增加复杂性有什么真正的好处吗?

我想你可以这样做:
1) 构建一个侦听器线程。对于每个连接,将套接字的副本发送到线程池
2) 建立一个线程池来处理请求

我使用管道在线程之间进行传输,而不使用I/O完成端口,性能非常出色。

设定控制限制,以确保资源不会耗尽。