IOCP线程与线程池处理消息
本文关键字:线程 消息 处理 IOCP | 更新日期: 2023-09-27 18:28:04
使用BeginReceive/EndReceive处理套接字IO时,回调由IOCP线程调用。
一旦你完成了接收,你需要处理数据。
- 你应该在回调的调用线程上执行吗
- 或者应该使用ThreadPool.QueueUserWorkItem运行任务
通常情况下,样本在回调线程上执行工作,这有点令人困惑。
如果您要处理几百个活动连接,那么在IOCP线程上运行处理最终会得到一个包含数百个线程的进程。ThreadPool有助于限制并发线程的数量吗?
我不知道每个人都有一个通用的"正确答案"——这将取决于您的个人用例。
如果您确实考虑采用ThreadPool路径,则需要考虑以下几点。
您可以支持无序/并发消息处理吗
如果套接字A连续快速地接收到消息1、2和3,它们可能会同时处理,或者出现故障。
.NET有每个CPU的线程池,如果一个CPU没有工作,它可能会从其他CPU"窃取"任务。这可能意味着您的消息可能会以某种随机顺序执行。
不要忘记考虑无序处理可能会对客户造成什么影响——例如,如果他们发送了三条需要响应的消息,那么无序发送响应可能会出现问题。
如果您必须按顺序处理每条消息,那么您可能必须实现自己的线程池。
您需要担心潜在的拒绝服务吗
如果一个套接字突然发送了大量数据,接受所有这些数据进行处理可能会阻塞内部队列和内存。您可能需要限制您接受的未处理数据的数量。
IOCP线程用于为IO操作提供服务。如果iocp回调执行的工作可能是长时间运行的,或者会导致锁或其他我阻止执行的功能,那么你最好把它交给工作线程。