c++网络编程下Linux的epoll技术和Windows下的IOCP模型

c++ 网络编程LINUX-epoll/windows-IOCP下socket opoll函数用法 优于select方法的epoll 以及windows下IOCP 解决多进程服务端创建进程资源浪费问题,感兴趣的小伙伴一起来学习吧

一、IOCP和Epoll之间的异同

1、异

1).IOCP是WINDOWS系统下使用。Epoll是Linux系统下使用。
2).IOCP是IO操作完毕之后,通过Get函数获得一个完成的事件通知。
Epoll是当你希望进行一个IO操作时,向Epoll查询是否可读或可写,若处于可读或可写状态,Epoll会通过epoll_wait进行通知。
3).IOCP封装了异步的消息事件的通知机制,同时封装了部分IO操作。但Epoll仅仅封装了一个异步事件的通知机制,并不负责IO读写操作。Epoll保持了事件通知和IO操作间的独立性,更加简单灵活。
4).基于上面的描述,我们可以知道Epoll不负责IO操作,所以它只告诉你当前可读可写了,并且将协议读写缓冲填充,由用户去读写控制,此时我们可以做出额外的许多操作。IOCP则直接将IO通道里的读写操作都做完了才通知用户,当IO通道里发生了堵塞等状况我们是无法控制的。

2、同

1).它们都是异步的事件驱动的网络模型。
2).它们都可以向底层进行指针数据传递,当返回事件时,除可通知事件类型外,还可以通知事件相关数据。

二:Epoll理解与应用。

1、epoll是什么?

epoll是当前在Linux下开发大规模并发网络程序的热门人选,epoll 在Linux2.6内核中正式引入,和select相似,都是I/O多路复用(IO multiplexing)技术。

Linux下设计并发网络程序,常用的模型有:
Apache模型(Process Per Connection,简称PPC)
TPC(Thread PerConnection)模型
select模型和poll模型。
epoll模型

2、epoll与select对比优化

基于select的I/O复用技术速度慢的原因:
1),调用select函数后常见的针对所有文件描述符的循环语句。它每次事件发生需要遍历所有文件描述符,找出发生变化的文件描述符。(以前写的示例没加循环)
2),每次调用select函数时都需要向该函数传递监视对象信息。即每次调用select函数时向操作系统传递监视对象信息,至于为什么要传?是因为我们监视的套接字变化的函数,而套接字是操作系统管理的。(这个才是最耗效率的)

注释:基于这样的原因并不是说select就没用了,在这样的情况下就适合选用select:1,服务端接入者少 2,程序应具有兼容性。

3、epoll是怎么优化select问题的

1),每次发生事件它不需要循环遍历所有文件描述符,它把发生变化的文件描述符单独集中到了一起。
2),仅向操作系统传递1次监视对象信息,监视范围或内容发生变化时只通知发生变化的事项。

实现epoll时必要的函数和结构体:

函数:
epoll_create:创建保存epoll文件描述符的空间,该函数也会返回文件描述符,所以终止时,也要调用close函数。(创建内存空间)
epoll_ctl:向空间注册,添加或修改文件描述符。(注册监听事件)
epoll_wait:与select函数类似,等待文件描述符发生变化。(监听事件回调)

结构体:

 struct epoll_event { __uint32_t events; epoll_data_t data; } typedef union epoll_data { void *ptr; int fd; __uinit32_t u32; __uint64_t u64; } epoll_data_t; 

三、epoll的几个函数的介绍:

1、epoll_create函数

 /** * @brief    该函数生成一个epoll专用的文件描述符。它其实是在内核申请一空间,用来存放你想关注的socket fd上是否发生以及发生了什么事件。 * * @param    size    size就是你在这个epoll fd上能关注的最大socket fd数 * * @return   生成的文件描述符 */ int epoll_create(int size);

2、epoll_ctl函数

 /** * @brief    该函数用于控制某个epoll文件描述符上的事件,可以注册事件,修改事件,删除事件。 * * @param    epfd    由 epoll_create 生成的epoll专用的文件描述符 * @param    op      要进行的操作例如注册事件,可能的取值EPOLL_CTL_ADD 注册、EPOLL_CTL_MOD 修 改、EPOLL_CTL_DEL 删除 * @param    fd      关联的文件描述符 * @param    event   指向epoll_event的指针 * * @return   0       succ *           -1      fail */ int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); 

其中用到的数据结构结构如下
op值:

  • EPOLL_CTL_ADD:注册新的fd到epfd中;
  • EPOLL_CTL_MOD:修改已经注册的fd的监听事件;
  • EPOLL_CTL_DEL:从epfd中删除一个fd;
 typedef union epoll_data { void *ptr; int fd; __uint32_t u32; __uint64_t u64; } epoll_data_t; struct epoll_event { __uint32_t events; /* Epoll events */ epoll_data_t data; /* User data variable */ }; 

常用的事件类型:

  • EPOLLIN :表示对应的文件描述符可以读;
  • EPOLLOUT:表示对应的文件描述符可以写;
  • EPOLLPRI:表示对应的文件描述符有紧急的数据可读
  • EPOLLERR:表示对应的文件描述符发生错误;
  • EPOLLHUP:表示对应的文件描述符被挂断;
  • EPOLLET: 表示对应的文件描述符有事件发生;

例:

 struct epoll_event ev; //设置与要处理的事件相关的文件描述符 ev.data.fd=listenfd; //设置要处理的事件类型 ev.events=EPOLLIN|EPOLLET; //注册epoll事件 epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&ev); 

3、epoll_wait函数

以上就是c++网络编程下Linux的epoll技术和Windows下的IOCP模型的详细内容,更多请关注0133技术站其它相关文章!

赞(0) 打赏
未经允许不得转载:0133技术站首页 » C语言