用于小型单线程应用程序的I/O完成端口
I/O Completion Port for small-scale, single-threaded applications?
让我在前面说我从未使用过I/O完成端口,尽管我已经听说它们很多年了。我的背景主要是select
、poll
、epoll
和WSAEventSelect
与WaitForMulitpleObjects
耦合。如果我对以下文本中的I/O完成端口有根本误解,请纠正我的错误。
作为工作项目的一部分,我的任务是开发模拟的插件(DLL),允许客户端连接到插件,并通过TCP向模拟发送/从模拟接收数据。插件充当服务器。该模拟模拟不同(非以太网)接口的通信信道,在这个特定的应用程序中,每个信道有一个套接字是有意义的。我不知道会有多少个客户端,也不知道每个客户端会打开多少个通道(套接字)。然而,我知道完全有可能会有64人以上,而且这不会是一个非常大的数字,最多可能不到1000人。
模拟的一个重要方面是只有当调用其test_cycle
函数时,才允许插件工作。在每个测试周期中,我需要:
- 接受来自客户端的任何新连接
- 从套接字接收数据并将其转发到模拟
- 从模拟中接收数据并将其转发给客户端
由于可能有超过64个套接字,我无法(轻松)使用WSAEventSelect
和WSAWaitForMultipleEvents
来检查是否可以读取套接字,或者客户端是否已正常终止连接。
所以我想了另外两种方法可以做到这一点。
-
每个插座应无堵塞。每次调用
test_cycle
时,都会循环遍历所有套接字,试图在每个套接字中接收最大数量的数据。 -
使用I/O完成端口并从套接字发出异步接收。在
test_cycle
中,重复调用GetQueuedCompletionStatus
,dwMilliseconds
参数设置为0
,直到指示超时(WAIT_TIMEOUT
?)。如果发生接收,请将下一个接收调用推迟到测试周期结束,这样客户端向服务器发送垃圾邮件就不会导致我们在test_cycle
中无限循环(希望如此)。
模拟的接口不是线程安全的,将数据转发到模拟的处理工作非常少,所以我认为为I/O完成端口提供工作线程不会有任何好处,因为它只会锁定并调用模拟API。但是,不必轮询每个套接字可能会获得更好的性能。
因此,对于这种规模的应用程序(最大不到1000个套接字,通常不到100个),使用I/O完成端口增加复杂性有什么真正的好处吗?
我想你可以这样做:
1) 构建一个侦听器线程。对于每个连接,将套接字的副本发送到线程池
2) 建立一个线程池来处理请求
我使用管道在线程之间进行传输,而不使用I/O完成端口,性能非常出色。
设定控制限制,以确保资源不会耗尽。
- 在C/C++中执行"_dl_init"(程序初始化)是单线程的吗
- 特定对象文件的单线程生成
- 如何在类中同时运行某些内容(在单线程平台中)?
- GDB 8.1 无法在单线程简单程序中跟踪 std::string 变量的值
- 双线程应用比单线程应用慢 C++ (VC++ 2010 Express).如何解决?
- OpenMP:共享同一算法的单线程和多线程实现
- std::原子布尔值或普通全局布尔值在单线程中很好吗?
- 重写多线程事件驱动的C 程序以使用单线程Boost :: Asio
- C++多线程操作比单线程慢
- 多线程和单线程代码维护
- 线程池的计时测试:单线程 vs 回调 tp vs 未来 tp
- 在 Linux 中从单独的单线程进程生成多线程进程时出现问题
- C++多线程性能比单线程代码慢
- 即使在单线程程序中,共享指针是否在引用计数中使用原子操作
- 从单线程到多线程图像处理
- 当发送多个同时请求时,单线程异步系统中Beast Boost异步HTTP客户端的行为
- 在单线程中使用 asio::async_write 时获得"the requested resource is in use"
- 在C++中,如何在并发读取和锁定的单线程写入uncodered_map之间进行交替
- wxWidgets-单线程多任务处理
- 用于小型单线程应用程序的I/O完成端口