完成端口详解和EPOLL详解

合集下载

Socket模型详解 两种模式

Socket模型详解 两种模式

// Create worker thread CreateThread(NULL, 0, WorkerThread, NULL, 0, &dwThreadId); while (TRUE) { // Accept a connection sClient = accept(sListen, (struct sockaddr *)&client, &iaddrSize); printf("Accepted client:%s:%d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port)); // Add socket to g_CliSocketArr g_CliSocketArr[g_iTotalConn++] = sClient; } return 0; } DWORD WINAPI WorkerThread(LPVOID lpParam) { int i; fd_set fdread; int ret; struct timeval tv = {1, 0}; char szMessage[MSGSIZE]; while (TRUE) { FD_ZERO(&fdread);//将fdread初始化空集 for (i = 0; i < g_iTotalConn; i++) { FD_SET(g_CliSocketArr, &fdread);//将要检查的套接口加入到集合中 } // We only care read event ret = select(0, &fdread, NULL, NULL, &tv);//每隔一段时间,检查可读性 的套接口 if (ret == 0) { // Time expired continue; } for (i = 0; i < g_iTotalConn; i++)

epoll的LT和ET使用EPOLLONESHOT

epoll的LT和ET使用EPOLLONESHOT

epoll的LT和ET使⽤EPOLLONESHOTepoll有两种触发的⽅式即LT(⽔平触发)和ET(边缘触发)两种,在前者,只要存在着事件就会不断的触发,直到处理完成,⽽后者只触发⼀次相同事件或者说只在从⾮触发到触发两个状态转换的时候⼉才触发。

这会出现下⾯⼀种情况,如果是多线程在处理,⼀个SOCKET事件到来,数据开始解析,这时候这个SOCKET⼜来了同样⼀个这样的事件,⽽你的数据解析尚未完成,那么程序会⾃动调度另外⼀个线程或者进程来处理新的事件,这造成⼀个很严重的问题,不同的线程或者进程在处理同⼀个SOCKET的事件,这会使程序的健壮性⼤降低⽽编程的复杂度⼤⼤增加!!即使在ET模式下也有可能出现这种情况!!解决这种现象有两种⽅法:第⼀种⽅法是在单独的线程或进程⾥解析数据,也就是说,接收数据的线程接收到数据后⽴刻将数据转移⾄另外的线程。

第⼆种⽅法就是本⽂要提到的EPOLLONESHOT这种⽅法,可以在epoll上注册这个事件,注册这个事件后,如果在处理写成当前的SOCKET后不再重新注册相关事件,那么这个事件就不再响应了或者说触发了。

要想重新注册事件则需要调⽤epoll_ctl重置⽂件描述符上的事件,这样前⾯的socket就不会出现竞态这样就可以通过⼿动的⽅式来保证同⼀SOCKET只能被⼀个线程处理,不会跨越多个线程。

看下⾯的代码:void Eepoll::ResetOneShot(int epollfd,SOCKET fd,bool bOne){epoll_eventevent;event.data.fd= fd;event.events= EPOLLIN | EPOLLET ;if(bOne){event.events |=EPOLLONESHOT;}if(-1 == epoll_ctl(epollfd,EPOLL_CTL_MOD,fd,&event)){perror("resetoneshotepoll_ctl error!");}}这⾥有⼀个问题,在操作ET模式下的EPOLL时,对EPOLLONESHOT没有什么太⼤的注意点,但是在LT时,就有⼀些注意的了。

epoll_wait使用案例

epoll_wait使用案例

标题:epoll_w本人t使用案例一、背景介绍epoll是Linux下高效的I/O多路复用机制,它在大规模并发连接的服务器中具有很高的性能表现。

相比于传统的select和poll,epoll具有更好的扩展性和效率。

二、epoll_w本人t函数简介epoll_w本人t是epoll中的一个函数,它用于等待事件的发生,并返回发生了事件的文件描述符集合。

三、epoll_w本人t函数的参数epoll_w本人t函数有三个参数:1. epfd:epoll文件描述符,即由epoll_create创建的epoll实例的文件描述符;2. events:用于存放发生事件的文件描述符集合;3. maxevents:最多监听的事件数。

四、epoll_w本人t函数的返回值epoll_w本人t函数的返回值为发生了事件的文件描述符的个数,如果没有事件发生则返回0,如果出错则返回-1。

五、epoll_w本人t函数的使用案例下面通过一个简单的案例来说明epoll_w本人t函数的使用。

```c#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/epoll.h>#define MAX_EVENTS 10int m本人n() {int epfd, nfds, i;struct epoll_event ev, events[MAX_EVENTS];// 创建epoll实例epfd = epoll_create(1);if (epfd == -1) {perror("epoll_create");exit(EXIT_F本人LURE);}// 添加监听的文件描述符ev.events = EPOLLIN;ev.data.fd = 0;if (epoll_ctl(epfd, EPOLL_CTL_ADD, 0, ev) == -1) {perror("epoll_ctl: fd 0");exit(EXIT_F本人LURE);}// 等待事件的发生nfds = epoll_w本人t(epfd, events, MAX_EVENTS, -1); if (nfds == -1) {perror("epoll_w本人t");exit(EXIT_F本人LURE);}// 处理发生的事件for (i = 0; i < nfds; i++) {if (events[i].data.fd == 0) {printf("stdin is readable\n");}}// 关闭epoll实例close(epfd);return 0;}```在上述案例中,首先创建了一个epoll实例,并添加了文件描述符0(即标准输入)作为监听对象,然后使用epoll_w本人t函数等待事件的发生。

IOCP

IOCP

完成IO使用总结IOCP(I/O Completion Port,I/O完成端口)是性能最好的一种I/O模型。

它是应用程序使用线程池处理异步I/O请求的一种机制。

在处理多个并发的异步I/O请求时,以往的模型都是在接收请求是创建一个线程来应答请求。

这样就有很多的线程并行地运行在系统中。

而这些线程都是可运行的,Windows内核花费大量的时间在进行线程的上下文切换,并没有多少时间花在线程运行上。

再加上创建新线程的开销比较大,所以造成了效率的低下。

调用的步骤如下:抽象出一个完成端口大概的处理流程:1:创建一个完成端口。

2:创建一个线程A。

3:A线程循环调用GetQueuedCompletionStatus()函数来得到IO操作结果,这个函数是个阻塞函数。

4:主线程循环里调用accept等待客户端连接上来。

5:主线程里accept返回新连接建立以后,把这个新的套接字句柄用CreateIoCompletionPort 关联到完成端口,然后发出一个异步的WSASend或者WSARecv调用,因为是异步函数,WSASend/WSARecv会马上返回,实际的发送或者接收数据的操作由WINDOWS系统去做。

6:主线程继续下一次循环,阻塞在accept这里等待客户端连接。

7:WINDOWS系统完成WSASend或者WSArecv的操作,把结果发到完成端口。

8:A线程里的GetQueuedCompletionStatus()马上返回,并从完成端口取得刚完成的WSASend/WSARecv的结果。

9:在A线程里对这些数据进行处理(如果处理过程很耗时,需要新开线程处理),然后接着发出WSASend/WSARecv,并继续下一次循环阻塞在GetQueuedCompletionStatus()这里。

归根到底概括完成端口模型一句话:我们不停地发出异步的WSASend/WSARecv IO操作,具体的IO处理过程由WINDOWS系统完成,WINDOWS系统完成实际的IO处理后,把结果送到完成端口上(如果有多个IO 都完成了,那么就在完成端口那里排成一个队列)。

Linux命令技巧利用lsof和netstat进行网络连接和端口监控

Linux命令技巧利用lsof和netstat进行网络连接和端口监控

Linux命令技巧利用lsof和netstat进行网络连接和端口监控Linux命令技巧:利用lsof和netstat进行网络连接和端口监控在Linux系统中,网络连接和端口监控是系统管理员和网络工程师必须掌握的技能。

本文将介绍如何使用lsof和netstat这两个强大的命令行工具来实现网络连接的监控和端口的查看。

一、lsof命令lsof(List Open Files)是一个用于查看Linux系统中打开的文件的命令。

除了查看文件外,它还可以用来查看网络连接。

下面是一些常用的lsof命令选项与实例:1. 查看指定端口的连接要查看指定端口的连接状态,可以使用以下命令:```shelllsof -i :port_number```其中,port_number是待查看的端口号。

例如,要查看80端口的连接状态,我们可以执行以下命令:```shelllsof -i :80```2. 查看活动的网络连接要查看系统上当前活动的网络连接,可以使用以下命令:```shelllsof -i```该命令将列出系统上所有活动的网络连接,包括连接类型、本地地址、远程地址和状态。

3. 查看指定进程的网络连接要查看指定进程的网络连接,可以使用以下命令:```shelllsof -p PID```其中,PID是进程的ID。

例如,要查看进程号为1234的进程的网络连接,我们可以执行以下命令:```shelllsof -p 1234```二、netstat命令netstat命令用于查看系统网络状态和网络连接信息。

下面是一些常用的netstat命令选项与实例:1. 查看所有网络连接要查看系统上所有的网络连接状态,可以使用以下命令:```shellnetstat -a```该命令将列出所有的网络连接信息,包括本地地址、远程地址、连接状态等。

2. 查看指定端口的监听情况要查看指定端口是否正在被监听,可以使用以下命令:```shellnetstat -tuln | grep port_number```其中,port_number是待查看的端口号。

epoll基本处理流程

epoll基本处理流程

epoll基本处理流程下载温馨提示:该文档是我店铺精心编制而成,希望大家下载以后,能够帮助大家解决实际的问题。

文档下载后可定制随意修改,请根据实际需要进行相应的调整和使用,谢谢!并且,本店铺为大家提供各种各样类型的实用资料,如教育随笔、日记赏析、句子摘抄、古诗大全、经典美文、话题作文、工作总结、词语解析、文案摘录、其他资料等等,如想了解不同资料格式和写法,敬请关注!Download tips: This document is carefully compiled by theeditor. I hope that after you download them,they can help yousolve practical problems. The document can be customized andmodified after downloading,please adjust and use it according toactual needs, thank you!In addition, our shop provides you with various types ofpractical materials,such as educational essays, diaryappreciation,sentence excerpts,ancient poems,classic articles,topic composition,work summary,word parsing,copy excerpts,other materials and so on,want to know different data formats andwriting methods,please pay attention!1. 创建 epoll 实例使用 `epoll_create` 函数创建一个 epoll 实例。

epoll工作模式详解

epoll工作模式详解

我们目前的网络模型大都是epoll的,因为epoll模型会比select模型性能高很多,尤其在大连接数的情况下,作为后台开发人员需要理解其中的原因。

select/epoll的特点select的特点:select 选择句柄的时候,是遍历所有句柄,也就是说句柄有事件响应时,select 需要遍历所有句柄才能获取到哪些句柄有事件通知,因此效率是非常低。

但是如果连接很少的情况下,select和epoll的LT触发模式相比,性能上差别不大。

这里要多说一句,select支持的句柄数是有限制的,同时只支持1024个,这个是句柄集合限制的,如果超过这个限制,很可能导致溢出,而且非常不容易发现问题,TAF就出现过这个问题,调试了n天,才发现:)当然可以通过修改linux的socket内核调整这个参数。

epoll的特点:epoll对于句柄事件的选择不是遍历的,是事件响应的,就是句柄上事件来就马上选择出来,不需要遍历整个句柄链表,因此效率非常高,内核将句柄用红黑树保存的。

对于epoll而言还有ET和LT的区别,LT表示水平触发,ET表示边缘触发,两者在性能以及代码实现上差别也是非常大的。

epoll的LT和ET的区别LT:水平触发,效率会低于ET触发,尤其在大并发,大流量的情况下。

但是LT对代码编写要求比较低,不容易出现问题。

LT模式服务编写上的表现是:只要有数据没有被获取,内核就不断通知你,因此不用担心事件丢失的情况。

ET:边缘触发,效率非常高,在并发,大流量的情况下,会比LT少很多epoll的系统调用,因此效率高。

但是对编程要求高,需要细致的处理每个请求,否则容易发生丢失事件的情况。

下面举一个列子来说明LT和ET的区别(都是非阻塞模式,阻塞就不说了,效率太低):采用LT模式下,如果accept调用有返回就可以马上建立当前这个连接了,再epoll_wait 等待下次通知,和select一样。

但是对于ET而言,如果accpet调用有返回,除了建立当前这个连接外,不能马上就epoll_wait 还需要继续循环accpet,直到返回-1,且errno==EAGAIN,TAF里面的示例代码:if(ev.events & EPOLLIN){do{struct sockaddr_in stSockAddr;socklen_t iSockAddrSize = sizeof(sockaddr_in);TC_Socket cs;cs.setOwner(false);//接收连接TC_Socket s;s.init(fd, false, AF_INET);int iRetCode = s.accept(cs, (struct sockaddr *) &stSockAddr, iSockAddrSize);if (iRetCode > 0){…建立连接}else{//直到发生EAGAIN才不继续acceptif(errno == EAGAIN){break;}}}while(true);}同样,recv/send等函数,都需要到errno==EAGAIN从本质上讲:与LT相比,ET模型是通过减少系统调用来达到提高并行效率的。

epollrdhup epollerr 用法

epollrdhup epollerr 用法

epollrdhup epollerr 用法epollrdhup和epollerr是在使用Linux的epoll机制时经常遇到的两个标志位。

本文将分析这两个标志位的用法,逐步回答相关问题,帮助读者深入了解它们的作用。

第一步,明确epoll机制在深入讨论epollrdhup和epollerr之前,我们先来了解一下epoll机制。

epoll是Linux内核提供的一种高效的IO事件通知机制,用于在大规模的并发场景下处理文件描述符的IO事件。

使用epoll机制,可以实现高并发的网络通信,提高服务器的性能。

第二步,理解epollrdhup标志位epollrdhup是epoll事件的一个标志位,用于标识对端关闭了写入端。

当对端关闭写入端时,会触发EPOLLRDHUP事件,表示读取的数据已经为空,此时可以断定对端已关闭连接。

第三步,认识epollerr标志位epollerr是epoll事件的另一个标志位,用于标识异常事件。

异常事件可能包括接收缓冲区溢出、连接异常断开等。

当文件描述符发生异常事件时,触发EPOLLERR事件,并由应用程序处理。

第四步,说明epollrdhup的用法在使用epoll机制时,我们可以通过设置epoll监视事件的过滤标志位,包括EPOLLIN、EPOLLOUT、EPOLLRDHUP和EPOLLERR。

对于epollrdhup标志位,一般是与EPOLLRDHUP事件一起使用。

以下是epollrdhup的用法示例:c++#include <sys/epoll.h>#include <unistd.h>int main() {int epollFd = epoll_create(10);struct epoll_event event;event.events = EPOLLIN EPOLLERR EPOLLRDHUP;event.data.fd = 0;epoll_ctl(epollFd, EPOLL_CTL_ADD, 0, &event);struct epoll_event events[10];while (true) {int n = epoll_wait(epollFd, events, 10, -1);for (int i = 0; i < n; ++i) {int fd = events[i].data.fd;if (events[i].events & EPOLLRDHUP) {对端关闭写入端close(fd);} else if (events[i].events & EPOLLIN) {读取数据char buffer[1024];ssize_t bytesRead = read(fd, buffer, sizeof(buffer));处理读取的数据} else if (events[i].events & EPOLLERR) {处理异常事件...}}}close(epollFd);return 0;}在上述代码中,我们通过设置event.events来指定监视的事件,包括EPOLLIN、EPOLLOUT、EPOLLRDHUP和EPOLLERR。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

由图可知,内核开始处理I/O操作到结束的时间段是T2~T3,这个时间 段中用户线程一直处于等待状态,如果这个时间段比较短,则不会有 什么问题,但是如果时间比较长,那么这段时间线程会一直处于挂起 状态,这就会很严重影响效率,所以我们可以考虑在这段时间做些事 情。
• 异步I/O
异步I/O操作则很好的解决了这个问题,它可以使得内核开始处理 I/O操作到结束的这段时间,让用户线程可以去做其他事情,从而提 高了使用效率。
Windows完成端口 Linux Fra bibliotekPOLL 解析
目录
1. Windows完成端口介绍 2. Linux EPOLL介绍
1. Windows完成端口
• 同步I/O与异步I/O 说起完成端口,它的实现机制其实是重叠 I/O实现异步I/O操作,下面就结合同步I/O来 解释下什么是异步I/O。
• 同步I/O 首先我们来看下同步I/O操作,同步I/O操作就是对于同一个I/O对 象句柄在同一时刻只允许一个I/O操作,原理图如下:
• 下面给出两个示例代码,方便大家理解 DWORD nReadByte ; BYTE bBuf[BUF_SIZE] ; OVERLAPPED ov = { 0, 0, 0, 0, NULL } ; // hEvent = NULL ; HANDLE hFile = CreateFile ( ……, FILE_FLAG_OVERLAPPED, …… ) ; ReadFile ( hFile, bBuf, sizeof(bBuf), &nReadByte, &ov ) ; // 由于此时hEvent=NULL,所以同步对象为hFile,下面两句的效果一样 WaitForSingleObject ( hFile, INFINITE ) ; //GetOverlappedResult ( hFile, &ov, &nRead, TRUE ) ; 这段代码在调用ReadFile后会立即返回,但在随后的 WaitForSingleObject或者GetOverlappedResult中阻塞,利用同步对象 hFile进行同步。 这段代码在这里可以实现正常的异步I/O,但存在一个问题,倘若现 在需要对hFile句柄进行多个I/O操作,就会出现问题。
• 异步过程调用实现异步I/O操作 异步过程调用(APC),即在特定的上下文中异步的执行一个调用。 在异步I/O中可以使用APC,即让操作系统的IO系统在完成异步I/O后立 即调用你的程序。 这里需要注意三点: (1) APC总是在调用线程中被调用; (2) 当执行APC时,调用线程会进入可变等待状态; (3) 线程需要使用扩展I/O系列函数,例如ReadFileEx,WriteFileEx, 另 外可变等待函数也是必须的(至少下面其中之一): WaitForSingleObjectEx WaitForMultipleObjectEx SleepEx SignalObjectAndWait MsgWaitForMultipleObjectsEx 在使用ReadFileEx,WriteFileEx时,重叠结构OVERLAPPED中的hEvent成 员并非一定要指定,因为系统会忽略它。当多个IO操作共用同一个完 成例程时,可以使用hEvent来携带序号等信息,用于区别不同的I/O操 作,因为该重叠结构会传递给完成例程。如果多个IO操作使用的完成 例程都不相同时,则直接把hEvent设置为NULL就可以了。
DWORD nReadByte ; BYTE bBuf1[BUF_SIZE],bBuf2[BUF_SIZE],bBuf3[BUF_SIZE] ; OVERLAPPED ov1 = { 0, 0, 0, 0, NULL } ; OVERLAPPED ov2 = { 0, 0, 0, 0, NULL } ; OVERLAPPED ov3 = { 0, 0, 0, 0, NULL } ; HANDLE hFile = CreateFile ( ……, FILE_FLAG_OVERLAPPED, …… ); ReadFile ( hFile, bBuf1, sizeof(bBuf1), &nReadByte, &ov1 ) ; ReadFile ( hFile, bBuf2, sizeof(bBuf2), &nReadByte, &ov2 ) ; ReadFile ( hFile, bBuf3, sizeof(bBuf3), &nReadByte, &ov3 ) ; //假设三个I/O处理的时间比较长,到这里还没有结束 GetOverlappedResult ( hFile, &ov1, &nRead, TRUE ) ; 这里对于hFile有三个重叠的I/O操作,但他们的同步对象却 都为hFile。使用GetOverlappedResult进行等待操作,这里 看似在等待第一个I/O处理的完成,其实只要有任何一个 I/O处理完成,该函数就会返回,相当于忽略了其他两个 I/O操作的结果。
完成端口
WindowsSockets应 用程序在调用 WSARecv()函数后立即 返回,线程继续运行。 当系统接收数据完成 后,向完成端口发送 通知包(这个过程对 应用程序不可见)。 应用程序在发起接收数据操作后,在完成端口上等 待操作结果。当接收到I/O操作完成的通知后,应用 程序对数据进行处理。
其实,这里有一个很重要的原则:对于一个重叠句柄上有多于 一个I/O操作的时候,应该使用事件对象而不是文件句柄来实现 同步。 DWORD nReadByte ; BYTE bBuf1[BUF_SIZE],bBuf2[BUF_SIZE],bBuf3[BUF_SIZE] ; HANDLE hEvent1 = CreateEvent ( NULL, FALSE, FALSE, NULL ) ; HANDLE hEvent2 = CreateEvent ( NULL, FALSE, FALSE, NULL ) ; HANDLE hEvent3 = CreateEvent ( NULL, FALSE, FALSE, NULL ) ; OVERLAPPED ov1 = { 0, 0, 0, 0, hEvent1 } ; OVERLAPPED ov2 = { 0, 0, 0, 0, hEvent2 } ; OVERLAPPED ov3 = { 0, 0, 0, 0, hEvent3 } ; HANDLE hFile = CreateFile ( ……, FILE_FLAG_OVERLAPPED, …… ) ; ReadFile ( hFile, bBuf1, sizeof(bBuf1), &nReadByte, &ov1 ) ; ReadFile ( hFile, bBuf2, sizeof(bBuf2), &nReadByte, &ov2 ) ; ReadFile ( hFile, bBuf3, sizeof(bBuf3), &nReadByte, &ov3 ) ; //此时3个I/O操作的同步对象分别为hEvent1,hEvent2,hEvent3 GetOverlappedResult ( hFile, &ov1, &nRead, TRUE ) ; 这样,这个GetOverlappedResult就可以实现对第一个I/O处理的 等待

使用重叠I/O实现异步I/O 重叠的意思,从资料上查询可以理解为同一个线程对多个I/O对象进行I/O操作,不同的线程也可以 对同一个I/O对象进行操作。 在使用重叠I/O时,线程需要创OVERLAPPED结构以供I/O处理。 OVERLAPPED的结构定义如下: typedef struct _OVERLAPPED { ULONG_PTR Internal; //被系统内部赋值,用来表示系统状态 ULONG_PTR InternalHigh; //被系统内部赋值,表示传输的字节数 union { struct { DWORD Offset; //与OffsetHigh合成一个64位的整数,用来表示从文件头部的多少字节开 始操作 DWORD OffsetHigh; //如果不是对文件I/O来操作,则Offset必须设定为0 }; PVOID Pointer; }; HANDLE hEvent; //如果不使用,就务必设为0;否则请赋一个有效的Event句柄 } OVERLAPPED, *LPOVERLAPPED; 该结构中最重要的成员是hEvent,它是作为一个同步对象而存在,如果hEvent为NULL,那么此时的 同步对象即为文件句柄、管道句柄等I/O操作对象。当I/O完成后,会使这里的同步对象受信,从而 通知用户线程。 由于在进行I/O请求后会立即返回,但有时用户线程需要知道I/O当前的执行情况,此时就可以使用 GetOverlappedResult。如果该函数的bWait参数为true,那么改函数就会阻塞线程直到目标I/O处理完 成为止;如果bWait为false,那么就会立即返回,如果此时的I/O尚未完,调用GetLastError就会返回 ERROR_IO_INCOMPLETE。
在系统调用完成例程有两个条件: (1) I/O操作必须完成 (2) 调用线程处于可变等待状态 对于第一个条件比较容易,显然完成例程只有在I/O 操作完成时才调用;至于第二个条件就需要进行认 为的控制,通过使用可变等待函数,让调用线程处 于可变等待状态,这样就可以执行完成例程了。这 里可以通过调节调用可变等待函数的时机来控制完 成例程的执行,即可以确保完成例程不会被过早的 执行。 当线程具有多个完成例程时,就会形成一个队列。 使用可变等待函数使线程进入可变等待状态时有一 个表示超时值的参数,如果使用INFINITE,那么只 有所有排队的完成例程被执行或者句柄获得信号时 该等待函数才返回。
• 完成端口的特点 Win32重叠I/O(Overlapped I/O)机制允许发起一个操作,并 在操作完成之后接收信息。对于那种需要很长时间才能完 成的操作来说,重叠IO机制尤其有用,因为发起重叠操作 的线程在重 叠请求发出后就可以自由地做别的事情了。在 WinNT和Win2000上,提供的真正可扩展的I/O模型就是使 用完成端口(Completion Port)的重叠I/O。 完成端口---是一种WINDOWS内核对象。完成端口用于异 步方式的重叠I/0情况下,当然重叠I/O不一定非得使用完 成端口不可,同样设备内核对象、事件对象、告警I/0等也 可使用。但是完成端口内部提供了线程池的管理,可以避 免反复创建线程的开销,同时可以根据CPU的个数灵活地 决定线程个数,而且可以减少线程调度的次数从而提高性 能。其实类似于WSAAsyncSelect和select函数的机制更容易 兼容Unix,但是难以实现我们想要的“扩展性”。而且 windows完成端口机制在操作系统的内部已经作了优化, 从而具备了更高的效率。
相关文档
最新文档