IOCP原理

简介

I/O完成端口是为多处理器系统处理多重异步I/O请求线程模型。
I/O完成端口就是与线程池配合使用的。

API

CreateIoCompletetionPort 创建IOCP和关联一个或多个句柄到端口上。
GetQueuedCompletionStatus 等待或从IOCP队列中取出完成包(completion packet)。
PostQueuedCompletionStatus 把一个完成包压入IOCP的队列。
CloseHandle 关闭IOCP

注意

  • 微软建议并发线程数指定为CPU核心数。
  • IOCP自动关联到创建它的进程且不能共享给其他进程。
  • 一个线程只能关联一个IOCP。
  • IOCP不能严格保证事件的出列顺序。
  • 微软建议应该先把IOCP所关联的资源(包括所关联的句柄)先释放,最后再释放IOCP。

原理

  • 调用GetQueuedComoletionStatus(第一次调用)的用户线程会被添加到等待线程队列。
  • 等待线程队列的LIFO机制使得性能更优。
  • 发生以下三种情况时,线程会与IOCP取消关联:
    - 线程退出。
    - 线程关联新的IOCP
    - IOCP关闭

I/O完成端口相关内核结构:

1. 设备列表
2. I/O完成队列(先入先出,FIFO)
3. 等待线程队列(后入先出,LIFO)
4. 已释放线程列表(可以理解为工作线程列表)
5. 已暂停线程列表

设备列表

内容:
• hDevice
• dwCompletionKey下·
添加:
• CreateIoCompletionPort被调用
删除:
• 设备句柄关闭

I/O完成队列(先入先出)

内容:
• dwBytesTransferred
• dwCompletionKey
• pOverlapped
• dwError
添加:
• I/O请求完成
• PostQueuedCompletionStatus
删除:
• 完成端口从等待线程队列中删除一项(GetQueuedCompletionStatus成功返回)

等待线程队列(后入先出)

内容:
• dwThreadId
添加:
• 线程调用GetQueuedCompletionStatus进入休眠状态。
删除:
• I/O完成队列不为空 && 已释放线程列表项数(即正在运行的工作线程数)小于最大并发线程数。(GetQueuedCompletionStatus会先从I/O完成队列中删除对应的项,接着将 dwThreadId转移到已释放线程列表,最后函数返回)。

已释放线程列表(可以理解为工作线程列表)

内容:
• dwThreadId
添加:
• 完成端口在等待线程队列中唤醒一个线程
• 已暂停的线程被唤醒
删除:
• 线程再次调用GetQueuedCompletionStatus(dwThreadId再次回到等待线程队列)
• 线程调用一个函数将自己挂起(dwThreadId转移到已暂停线程列表)

已暂停线程列表

内容:
• dwThreadId
添加:
• 已释放的线程调用一个函数将自己挂起
删除:
• 已挂起的线程被唤醒(dwThread回到已释放线程队列)

猜你喜欢

转载自blog.csdn.net/bnbjin/article/details/78732437
今日推荐