I/O Completion Ports

I/O Completion PortsI/O completion ports provide an efficient threading model for processing multiple asynchronous I/O requests on a multiprocessor system.

When a process creates an I/O completion port, the system creates an associated queue object for requests whose sole purpose is to service these requests.

Processes that handle many concurrent asynchronous I/O requests can do so more quickly and efficiently by using I/O completion ports

in conjunction with a pre-allocated thread pool than by creating threads at the time they receive an I/O request.

I/O完成端口提供在一个多核处理器系统上面处理多个异步I/O请求的高效线程模型.

当创建一个I/O 完成端口时,操作系统创建与I/O完成端口相关联的队列对象来处理这些I/O请求.

I/O完成端口使用和一个预先分配好的线程池相结合,而不是接收I/O请求时才创建线程的方式来高效快速的处理多个并发异步I/O请求.

How I/O Completion Ports Work

The CreateIoCompletionPort function creates an I/O completion port and associates one or more file handles with that port.

When an asynchronous I/O operation on one of these file handles completes, an I/O completion packet is queued in first-in-first-out (FIFO) order to the associated I/O completion port.

One powerful use for this mechanism is to combine the synchronization point for multiple file handles into a single object, although there are also other useful applications.

Please note that while the packets are queued in FIFO order they may be dequeued in a different order.

CreateIoCompletionPort()可以创建一个I/O 完成端口并且可以和一个或者多个Socket相管理.

当这些异步Socket完成时,一个I/O 完成端口数据包将按照先进先出(FIFO)顺序在完成端口上排队.

注意:虽然数据包按照FIFL顺序排队,但是不一定按照FIFL顺序出队列.

When a file handle is associated with a completion port, the status block passed in will not be updated until the packet is removed from the completion port.

The only exception is if the original operation returns synchronously with an error.

A thread (either one created by the main thread or the main thread itself) uses the GetQueuedCompletionStatus function to wait for a completion packet to be queued to the I/O completion port,

rather than waiting directly for the asynchronous I/O to complete.

Threads that block their execution on an I/O completion port are released in last-in-first-out (LIFO) order, and the next completion packet is pulled from the I/O completion port‘s FIFO queue for that thread.

This means that, when a completion packet is released to a thread, the system releases the last (most recent) thread associated with that port,

passing it the completion information for the oldest I/O completion.

当一个Socket和一个完成端口相关联时,直到the packet 从完成端口移除时,阻塞状态才被更新.

一个线程使用GetQueuedCompletionStatus()函数来等到数据包在完成端口上面排队,而不是等到异步I/O操作的完成.

在I/O完成端口上面的阻塞线程将按照后进先出顺序被释放,然而,数据包是按照FIFL顺序从完成端口上弹出等待线程处理.

这就意味着,当一个数据包从队列中弹出时,将是线程池中最后一个被释放的线程.

Although any number of threads can call GetQueuedCompletionStatus for a specified I/O completion port,

when a specified thread calls GetQueuedCompletionStatus the first time, it becomes associated with the specified I/O completion port until one of three things occurs:

1 The thread exits,

2 specifies a different I/O completion port

3 closes the I/O completion port

In other words, a single thread can be associated with, at most, one I/O completion port.

当指定的线程第一次调用GetQueuedCompletionStatus()时,线程将和指定的完成端口相关联,直到下面任意事件的发生:

1 The thread exits,

2 specifies a different I/O completion port

3 closes the I/O completion port

换言之,一个线程最多和一个完成端口相关联

When a completion packet is queued to an I/O completion port, the system first checks how many threads associated with that port are running.

If the number of threads running is less than the concurrency value , one of the waiting threads (the most recent one) is allowed to process the completion packet.

When a running thread completes its processing, it typically calls GetQueuedCompletionStatus again, at which point it either returns with the next completion packet or waits if the queue is empty.

当一个Completion Packet 在完成端口排队时,操作系统首先检查在线程池中和完成端口关联的正在运行的线程.

当正在运行的线程数量小于指定的并发值,等待的线程将被允许处理Completion Packet.

当一个运行中的线程处理完Completion Packet后,将再次调用GetQueuedCompletionStatus()处理下一个Completion Packet.如果等待队列为空,GetQueuedCompletionStatus()将阻塞.

Threads can use the PostQueuedCompletionStatus function to place completion packets in an I/O completion port‘s queue.

By doing so, the completion port can be used to receive communications from other threads of the process, in addition to receiving I/O completion packets from the I/O system.

The PostQueuedCompletionStatus function allows an application to queue its own special-purpose completion packets to the I/O completion port without starting an asynchronous I/O operation

This is useful for notifying worker threads of external events, for example.

Threads and Concurrency

The most important property of an I/O completion port to consider carefully is the concurrency value.

The concurrency value of a completion port is specified when it is created with CreateIoCompletionPort via the NumberOfConcurrentThreads parameter.

This value limits the number of runnable threads associated with the completion port.

When the total number of runnable threads associated with the completion port reaches the concurrency value,

the system blocks the execution of any subsequent threads associated with that completion port until the number of runnable threads drops below the concurrency value.

在完成端口中最重要的属性并且被小心使用的是并发值.

并发值时在使用CreateIoCompletionPort()函数创建IOCP对象时,通过NumberOfConcurrentThreads 参数来设置.

并发值限制可以在完成端口上面同时运行线程最多数量.

当正在运行线程数量大于并发值时,系统将阻塞任何后来的线程.直到正在运行的线程数量小于并发值.

The most efficient scenario occurs when there are completion packets waiting in the queue, but no waits can be satisfied because the port has reached its concurrency limit.

Consider what happens with a concurrency value of one and multiple threads waiting in the GetQueuedCompletionStatus function call.

In this case, if the queue always has completion packets waiting, when the running thread calls GetQueuedCompletionStatus, it will not block execution because, as mentioned earlier, the thread queue is LIFO.

Instead, this thread will immediately pick up the next queued completion packet.

No thread context switches will occur, because the running thread is continually picking up completion packets and the other threads are unable to run.

使用完成端口最高效的方案是处理完成端口数据包的线程达到并发值后,不存在等待的线程.

当到达并发值时,一个线程调用GetQueuedCompletionStatus()将会发生什么?

当一个数据包到达完成端口时,一个运行的线程调用GetQueuedCompletionStatus()函数,该线程不会阻塞立即执行,并继续处理下一个数据包.因为线程是LILO 后进先出顺序.

因为一个运行的线程可以立刻处理完成端口的数据包,所有其他线程将不能运行,因为不存在线程上下文切换.

时间: 2024-12-29 01:31:02

I/O Completion Ports的相关文章

(转)I/O Completion Ports学习

http://www.cnblogs.com/xiangshancuizhu/p/3325980.html IO完成端口为在多处理器系统处理多个异步IO请求提供一个高效的线程模型.当一个进程新建一个完成端口,操作系统新建一个目的为服务这些请求的队列对象.通过利用IO完成端口与相关联的预先分配的线程池而不是新建线程来处理当前请求,处理多个并发的异步IO请求会更快更有效. IO完成端口如何工作 函数CreateIoCompletionPort创建一个IO完成端口,并在这个端口上关联一个或多个file

ECHOSRV.C中的main()设立一个 I/O completion port

#include<Windows.h> int main(int argc, char* argv[]) { SOCKET listener; SOCKET newsocket; WSADATA WsaData; struct sockaddr_in serverAddress; struct sockaddr_in clientAddress; int clientAddressLength; int err; CheckOsVersion(); err = WSAStartup(0x010

理解I/O Completion Port

欢迎阅读此篇IOCP教程.我将先给出IOCP的定义然后给出它的实现方法,最后剖析一个Echo程序来为您拨开IOCP的谜云,除去你心中对IOCP的烦恼.OK,但我不能保证你明白IOCP的一切,但我会尽我最大的努力.以下是我会在这篇文章中提到的相关技术: I/O端口 同步/异步 堵塞/非堵塞 服务端/客户端 多线程程序设计 Winsock API 2.0 在这之前,我曾经开发过一个项目,其中一块需要网络支持,当时还考虑到了代码的可移植性,只要使用 select,connect,accept,list

[转]理解I/O Completion Port

原文:http://dev.gameres.com/Program/Control/IOCP.htm 另附上:http://stackoverflow.com/questions/5283032/i-o-completion-ports-advantages-and-disadvantages 欢迎阅读此篇IOCP教程.我将先给出IOCP的定义然后给出它的实现方法,最后剖析一个Echo程序来为您拨开IOCP的谜云,除去你心中对IOCP的烦恼.OK,但我不能保证你明白IOCP的一切,但我会尽我最大

理解I/O Completion Port(完成端口)(转载)

欢迎阅读此篇IOCP教程.我将先给出IOCP的定义然后给出它的实现方法,最后剖析一个Echo程序来为您拨开IOCP的谜云,除去你心中对IOCP的烦恼.OK,但我不能保证你明白IOCP的一切,但我会尽我最大的努力.以下是我会在这篇文章中提到的相关技术: I/O端口 同步/异步 堵塞/非堵塞 服务端/客户端 多线程程序设计 Winsock API 2.0 在这之前,我曾经开发过一个项目,其中一块需要网络支持,当时还考虑到了代码的可移植性,只要使用select,connect,accept,liste

.NET线程控制快速学习01

最近,由于基础框架的整体升级,因此需要更新所有相关项目的DLL文件.这个过程存在不小的风险,因此也对发布后的生产服务器进行了密切的监控,结果还是出现了个别应用出现异常的情况,很快的占用了大量的服务器内存和CPU等资源.通过研究dump,初步发现是由于配置服务器出现单点故障,然后应用通过多线程调用相关SOA服务时出现异常,引发了ThreadAbortException异常,而且由于原有异常处理代码不够严谨,而且与异步发送报警邮件紧密结合在一起,造成线程数量的几何级增加,最终使得整个服务器不可用.这

WINDOWS操作系统中可以允许最大的线程数

默认情况下,一个线程的栈要预留1M的内存空间 而一个进程中可用的内存空间只有2G,所以理论上一个进程中最多可以开2048个线程 但是内存当然不可能完全拿来作线程的栈,所以实际数目要比这个值要小. 你也可以通过连接时修改默认栈大小,将其改的比较小,这样就可以多开一些线程. 如将默认栈的大小改成512K,这样理论上最多就可以开4096个线程. 即使物理内存再大,一个进程中可以起的线程总要受到2GB这个内存空间的限制. 比方说你的机器装了64GB物理内存,但每个进程的内存空间还是4GB,其中用户态可用

windows下nginx安装、配置与使用

目前国内各大门户网站已经部署了Nginx,如新浪.网易.腾讯等:国内几个重要的视频分享网站也部署了Nginx,如六房间.酷6等.新近发现Nginx 技术在国内日趋火热,越来越多的网站开始部署Nginx. 相比apeach.iis,nginx以轻量级.高性能.稳定.配置简单.资源占用少等优势广受欢迎. 1)下载地址: http://nginx.org 2)启动 解压至c:\nginx,运行nginx.exe(即nginx -c conf\nginx.conf),默认使用80端口,日志见文件夹C:\

网络编程——The C10K Problem(C10K = connection 10 kilo 问题)。k 表示 kilo,即 1000

The C10K problem翻译 (C10K = connection 10 kilo 问题).k 表示 kilo,即 1000 比如:kilometer(千米), kilogram(千克). 如今的web服务器需要同时处理一万个以上的客户端了,难道不是吗?毕竟如今的网络是个big place了. 现在的计算机也很强大了,你只需要花大概$1200就可以买一个1000MHz的处理器,2G的内存, 1000Mbit/sec的网卡的机器.让我们来看看--20000个客户,每个为50KHz,100K