从william kennedy那里整理过来的,不同之处在于他自己定义了一个overlapped,而我们这里直接使用 system.threading.nativeoverlapped.
附一段我以前的win32下的iocp文档,如果您了解iocp也可以直接跳过看后面的c#测试示范: 【程序编程相关:基于ASP.NET实现全球化】【推荐阅读:.net 里面 protected pr】
【扩展信息:分享:处理Excel方法小结】整理者:郑昀@ultrapower
我们采用的是i/o complete port(以下简称iocp)处理机制.简单的讲,当服务应用程序初始化时,它应该先创建一个i/o cp.我们在请求到来后,将得到的数据打包用postqueuedcompletionstatus发送到iocp中.这时需要创建一些个线程(7个线程/每cpu,再多就没有意义了)来处理发送到iocp端口的消息.实现步骤大致如下:1 先在主线程中调用createiocompletionport创建iocp.createiocompletionport的前三个参数只在把设备同complete port相关联时才有用.此时我们只需传递invalid_handle_value,null与0即可.第四个参数告诉端口同时能运行的最多线程数,这里设置为0,表示默认为当前计算机的cpu数目.2 我们的threadfun线程函数执行一些初始化之后,将进入一个循环,该循环会在服务进程终止时才结束.在循环中,调用getqueuedcompletionstatus,这样就把当前线程的id放入一个等待线程队列中,i/o cp内核对象就总能知道哪个线程在等待处理完成的i/o请求.如果在idle_thread_timeout规定的时间内i/o cp上还没有出现一个completion packet,则转入下一次循环.在这里我们设置的idle_thread_timeout为1秒.
当端口的i/o完成队列中出现一项时,完成端口就唤醒等待线程队列中的这个线程,该线程将得到完成的i/o项中的信息: 传输的字节数.完成键与overlapped结构的地址.
在我们的程序中可以用智能指针或者bstr或者int来接受这个overlapped结构的地址的值,从而得到消息;然后在这个线程中处理消息.getqueuedcompletionstatus的第一个参数hcompletionport指出了要监视哪一个端口,这里我们传送先前从createiocompletionport返回的端口句柄.
需要注意的是:第一, 线程池的数目是有限制的,与cpu数目有关系.第二, iocp是一种较为完美的睡眠/唤醒 线程机制;线程当前没有任务要处理时,就进入睡眠状态,从而不占用cpu资源,直到被内核唤醒;第三, 最近一次刚执行完的线程,下次任务来的时候还会唤醒它;所以有可能比较少被调用的线程以后被调用的几率也少.
测试代码:
... 下一页