I/O Completion Ports学习
表示还是自己看MSDN最直接,别人的介绍都是嚼剩下,有木有?
IO完成端口为在多处理器系统处理多个异步IO请求提供一个高效的线程模型。当一个进程新建一个完成端口,操作系统新建一个目的为服务这些请求的队列对象。通过利用IO完成端口与相关联的预先分配的线程池而不是新建线程来处理当前请求,处理多个并发的异步IO请求会更快更有效。
函数CreateIoCompletionPort创建一个IO完成端口,并在这个端口上关联一个或多个file【文件描述符】。当在这些操作符上的一个或者多个的一个异步IO操作完成时,一个IO完成包(packet)就进入与IO完成端口关联的先进先出队列。这个机制的一个强大的用法是在单个对象里进行多个描述符间的同步,尽管他们还有其他有用的应用。请注意:在队列中的数据包可能会以不同的顺序出列。【这句不怎么理解,是不是多个线程在出列操作?】
注意:
属于file handle是代表重叠IO端点的一种系统抽象代表,而不只是磁盘上的file。例如,可以是网络端点,TCP socket,命名管道或者mail slot。任何支持完成端口的系统对象都可以被利用。
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.
当描述符与一个完成端口相关联,传进来的状态快不会被更新直到包从完成端口上拿走。唯一的异常是原来的操作异步返回错误。一个线程(可以是主线程创建的或者主线程自己)用GetQueuedCompletionStatus 函数来等待进入完成端口的包,而不是直接等待异步IO完成。在完成端口阻塞操作的线程会以后进显出释放,而这个线程的下一个端口包会以先进先出队列从IO端口取出。这就意味着,当一个包喂给了一个线程,系统将释放最后一个与端口关联的线程,同时为最老的完成端口传递完成端口信息【这句没怎么看懂】。
尽管任何线程都能向特定的完成端口调用GetQueuedCompletionStatus,当一个具体的线程第一次调用它时,它开始与特定的完成端口关联知道以下三种情况中的一种发生:
1.线程存在,关联了另外一个完成端口;
2.关闭了完成端口。
也就是说一个线程只能关联一个完成端口。
当一个完成包被放入完成端口的队列中,系统首先检查当前有多少与端口关联的线程。如果运行中的线程数目小于并发值,最近的一个等待线程被允许处理完成包。当一个运行线程完成处理,它将要继续再次调用GetQueuedCompletionStatus,因为在这个点它要么等待下一个完成包,要么等待到包队列为空。
线程可以调用PostQueuedCompletionStatus来投递完成包到IO端口的队列。通过这样做,完成端口可以用来收取其他线程或者进程的交互数据,还可以从IO系统收取完成端口包。PostQueuedCompletionStatus函数允许应用程序不开启异步IO操作,就能向IO完成端口投递特定的完成包。比如,这对于以外不事件通知工作线程是有用的。
IO完成端口句柄和每个描述符句柄与特定IO完成端口关联被认为提领了完成端口,当没有与它关联的引用时完成端口被释放。因此,所有这些句柄必须被适合地关心以释放完成端口和它关联的系统资源。这些条件满足后,通过调用CloseHandle来关闭完成端口句柄。
注意
一个完成端口与创建它的进行关联,不能被进程间共享。然而,单个句柄可以在同一进程的不同线程中共享。
IO完成端口的最重要的性质是并发值。完成端口的并发值在通过CreateIoCompletionPort的theNumberOfConcurrentThreads参数被确定。这个值限制了与完成端口相关联的线程的数目。当关联线程数目超过了这个并发值,系统将会阻塞任何之后的线程,直到运行线程数目降到并发值。
最有效的语义是当有完成包在队列里,但没有等待会被满足因为端口已经达到并发限制。考虑到在并发值下,用一个或多个线程等待在GetQueuedCompletionStatus调用。在这种情况下,如果队列有完成包在等待,当运行线程调用GetQueuedCompletionStatus,他将不会阻塞,因为如上面提到的线程队列是先进先出的。取而代之的是,这个线程将立即拿到下一个完成包。没有上下文切换发生,因为运行线程连续地拿完成包,另外的线程不能运行【这段都怎么理解】。
注意
在前面的例子里,额外的线程好像是无用的,并且不会允许,但假设运行线程因为某些同步机制从未进入等待状态,停止或者关闭它关联的完成端口。注意当重新设计应用的时候所有这些线程的执行分支。
最好的并发最大值是电脑的CPU个数。如果你的传输要求一个复杂的计算,这就需要大点的并发值。每个完成包可能完成的时间增加,但更多的完成包被并发地处理。你可以试验设置并发值来达到程序的最优化。
系统运行当一关联同一完成端口的线程因为一些原因(例如SuspendThread函数)在等待状态时,另一线程等待在GetQueuedCompletionStatus来处理完成包。当这个在等待状态的线程开始运行,当活跃线程数目超过并发值这将是一个短暂的过程。然而,系统将通过不允许任何启动新的活跃线程迅速减少活跃线程数目,直到活跃线程数目下降到并发值。这也是你可以在线程池里创建比并发值多的线程的原因。线程池管理超越了本话题的范围,但是一个好的经验是在线程池里最少拥有系统处理器两倍的线程数(>=2*corenum)。可以参考 Thread Pools。
下列的函数可以被用来通过利用完成端口来启动IO操作。你必须传递OVERLAPPED结构的一个实例和之前与IO关联的描述符给这些函数(通过调用CreateIoCompletionPort)来开启IO完成端口机制:
- ConnectNamedPipe
- DeviceIoControl
- LockFileEx
- ReadDirectoryChangesW
- ReadFile
- TransactNamedPipe
- WaitCommEvent
- WriteFile
- WSASendMsg
- WSASendTo
- WSASend
- WSARecvFrom
- WSARecvMsg
- WSARecv
ok,翻译完了,很多句子不通顺啊,有的地方自己都不明白啊!
I/O Completion Ports学习的更多相关文章
- I/O Completion Ports
http://weblogs.asp.net/kennykerr/parallel-programming-with-c-part-4-i-o-completion-ports http://webl ...
- [转]理解I/O Completion Port
原文:http://dev.gameres.com/Program/Control/IOCP.htm 另附上:http://stackoverflow.com/questions/5283032/i- ...
- Window I/O 完成端口 (Windows I/O Completion Port (IOCP))
相关对象 IO EndPoint, 所有支持重叠IO(overlapped IO)的设备,比如文件,Winsock,管道等. IOCP, IO完成端口内核对象,可以使用API CreateIoComp ...
- 理解I/O Completion Port
欢迎阅读此篇IOCP教程.我将先给出IOCP的定义然后给出它的实现方法,最后剖析一个Echo程序来为您拨开IOCP的谜云,除去你心中对IOCP的烦恼.OK,但我不能保证你明白IOCP的一切,但我会尽我 ...
- Proactor 学习1
Proactor An Object Behavioral Pattern for Demultiplexingand Dispatching Handlers for Asynchronous ...
- IOS开发之XCode学习009:UIViewController使用
此文学习来源为:http://study.163.com/course/introduction/1002858003.htm 此工程文件实现功能: 通过点击屏幕事件,调用ViewController ...
- 理解I/O Completion Port(完成端口)
欢迎阅读此篇IOCP教程.我将先给出IOCP的定义然后给出它的实现方法,最后剖析一个Echo程序来为您拨开IOCP的谜云,除去你心中对IOCP的烦恼.OK,但我不能保证你明白IOCP的一切,但我会尽我 ...
- [转载]理解 I/O Completion Port (IOCP完成端口)
原文:理解 I/O Completion Port (IOCP完成端口)欢迎阅读此篇IOCP教程.我将先给出IOCP的定义然后给出它的实现方法,最后剖析一个Echo程序来为您拨开IOCP的谜云,除去你 ...
- IOCP Input/Output Completion Port IO完成端口
I/O completion ports provide an efficient threading model for processing multiple asynchronous I/O r ...
随机推荐
- UML图中聚合、组合、关联、依赖、泛化的强弱关系
一.泛化 1.说明 泛化是一种继承关系,如果一个类A的所有属性和操作能被另一个类B所继承,则类B不仅可以包含自己独有的属性,而且可以包含类A的属性和操作.继承是类与类或者类与接口之间最常见的关系. 2 ...
- OJ模板库
近期刷了好几次的oj,好受伤好多都是相似的题目. 最长回文子串 string preprocess(string &str) { string afterProcessStr="#& ...
- bash: php: command not found
bash: php: command not found 解决:export PATH=$PATH:/usr/local/php/bin
- capwap学习笔记——初识capwap(二)
2.5.1 AC发现机制 WTP使用AC发现机制来得知哪些AC是可用的,决定最佳的AC来建立CAPWAP连接. WTP的发现过程是可选的.如果在WTP上静态配置了AC,那么WTP并不需要完成AC的发现 ...
- extjs_08_界面布局
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYWRhbV93enM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA ...
- 编译GSLSDevil的全过程
GLSLDevil是调试OpenGL程序的工具. GLSLDevil的新版本已经改名为GLSL-Debugger, github的地址在这里:http://glsl-debugger.github ...
- [Git] Change the commit message of my last commit
Did you make a typo in your last commit message? No problem, we can use the git --amend command to c ...
- C#.NET常见问题(FAQ)-如何在不同窗体之间传递值
最简单的方法是在定义窗体的时候就写好几个变量,在实例化Form2的时候,就把这些参数传递过去 或者你也可以定义一个类,然后通过这个类的静态变量交互(注意只能用静态的,因为Form2无法访问Form ...
- angularJS 事件广播与接收[转]
路由的事件 事件这个词在前端出现的频率真是高,根本拦不住,哪都是.$route服务在路由过程中的每个阶段都会触发不同的事件,可以为这些不同的路由事件设置监听器并做出响应. 一共有4个事件用来监听路由的 ...
- mysql版本导致的hibernate 方言问题
今天在看hibernate视频时,看到视频上人家的hibernate.cfg.xml配置文件在配置hibernate方言时,发现视频上是这样写的<property name="dial ...