NoteDeep
完成端口是Windows的一种机制, 在重叠IO模型基础上的优化

重叠IO存在的问题:

事件通知:

1.无序
2.循环询问:延迟高, 有些无用功
3.如果采用了多线程, 不好管理, 需要线程过多, 如果有响应客户端都在一个线程中管理, 相当于单线程, 其他线程都是闲置的

完成例程:

没有无序的问题(操作系统内部调用回调函数, 由操作系统决定)
不用循环和无用功
采用了多线程:每个客户端同时响应, 都给一个线程, 数量太多> 事件通知

线程过多:

切换线程需要消耗大量时间。
CPU单核多线程的执行状态
在一个时间片中, 每个线程执行一样的时间:电脑开太多软件会卡
单核是伪多线程

单核中执行多线程, 理论上还是单线程的执行效率
假设一条线程执行完需要1秒, 10条依然需要10秒, 还要加上切换线程的时间, 所以>10秒

多核达到了真正的同时运行。

最优线程数量:
理论上:CPU核数

最优:
CPU核数
CPU核数 * 2:超线程技术
CPU核数 * 2 + 2:实际应用中的经验, 如果有线程挂起/睡眠等操作, 就多创建出来一些线程, 时刻满状态工作

4个内核8个逻辑处理器:4核8线程
理论上4核4个线程, 但是intel使用了超线程技术, 使得一个物理内核可以模拟出双核的性能
相当于8核

考虑:
给一个软件创建的线程过多, 其他软件分的时间片就会减少
考虑切换时间

完成端口:

模仿消息队列, 系统创建了一个通知队列:有序, 不做无用功
创建最佳数量的线程, 充分利用CPU的性能


原理:

将所有的套接字和一个完成端口(一个类型的变量)绑定到一起
使用AcceptEx、WSARecv、WSASend投递
当系统异步完成请求, 就会把通知放进一个队列, 该队列由操作系统创建维护
通过GetQueuedCompletionStaus从队列中一个一个拿处理

创建完成端口:

CreateCompletionPort()

将完成端口和socket绑定:

CreateCompletionPort()

创建指定数目的线程:

CreateThread()

线程中分类处理:

GetQueuedCompletionStatus()

使用AcceptEx、WSARecv、WSASend:

AcceptEx()
WSARecv()
WSASend()

主线程阻塞


优化:

细节可以优化












评论列表

    重叠IO存在的问题:
    完成端口:
    原理:
    创建完成端口:
    将完成端口和socket绑定:
    创建指定数目的线程:
    使用AcceptEx、WSARecv、WSASend:
    主线程阻塞
    优化: