epoll 边沿触发 非阻塞 IO 服务器
在之前的文章中提到过Readn 函数:
ssize_t Readn(int fd, void *vptr, size_t n)
试想这样一种情况:
1、server 循环使用 epoll_wait,监听 fd,fd 发生读事件,epoll_wait 通知 server。
2、server 接到通知,调用 Readn 函数,读取 500 字节。
3、但是,client 就发送了 200 字节,不足 500 字节。
4、此时,server 会阻塞在 Readn 函数上。
5、意味着 server 无法执行下一次 epoll_wait,意味着即使 client 再给 server 发数据,server 也得不到通知。
6、server 得不到通知,就无法读数据,就无法解除 Readn 函数的阻塞。
结果:造成“死锁”现象。
解决:将“套接字的文件描述符”设置为非阻塞 。
int flag = fcntl(cfd, F_GETFL); // 获得文件原属性
flag |= O_NONBLOCK; // 添加非阻塞属性
fcntl(connfd, F_SETFL, flag); // 使非阻塞属性生效
epoll的“边沿模式”下的“非阻塞读”模型
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/epoll.h>
#include <unistd.h>
#include <fcntl.h>
#define MAXLINE 10
#define SERV_PORT 8000
int main(void)
{struct sockaddr_in servaddr;socklen_t cliaddr_len;int listenfd, connfd;char buf[MAXLINE];char str[INET_ADDRSTRLEN];int efd, flag;listenfd = socket(AF_INET, SOCK_STREAM, 0); // 创建套接字bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = htonl(INADDR_ANY);servaddr.sin_port = htons(SERV_PORT);bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); // 绑定端口和IPlisten(listenfd, 20); // 设置同时访问上限数struct epoll_event event; // epoll_ctl 传入参数struct epoll_event resevent[10]; // epoll_wait 传出参数int res, len;efd = epoll_create(10); // 创建epoll树根event.events = EPOLLIN | EPOLLET; /* ET 边沿触发,默认是水平触发 */printf("Accepting connections ...\n");truct sockaddr_in cliaddr;cliaddr_len = sizeof(cliaddr);connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len); // 阻塞等待连接,获得connfdprintf("received from %s at PORT %d\n",inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),ntohs(cliaddr.sin_port)); // 获得客户端信息flag = fcntl(connfd, F_GETFL); /* 修改connfd为非阻塞读 */ // connfd 设置为非阻塞flag |= O_NONBLOCK;fcntl(connfd, F_SETFL, flag);event.data.fd = connfd; // 至此epoll_ctl 传入参数设置完毕epoll_ctl(efd, EPOLL_CTL_ADD, connfd, &event); // 将connfd加入监听红黑树while (1) {printf("epoll_wait begin\n");res = epoll_wait(efd, resevent, 10, -1); // 最多10个, 阻塞监听printf("epoll_wait end res %d\n", res);if (resevent[0].data.fd == connfd) {while ((len = read(connfd, buf, MAXLINE / 2)) > 0) write(STDOUT_FILENO, buf, len); }}return 0;
}
// 如果是 非阻塞,边沿触发:read 不会阻塞,wait 只调用 1 次,while 循环 2 次
// 如果是 非阻塞,水平触发:read 不会阻塞,wait 需调用 2 次,while 循环 2 次
epoll 边沿触发 非阻塞 IO 服务器相关推荐
- java epoll select_Java 非阻塞 IO 和异步 IO
点击上方 Java后端,选择 设为星标 优质文章,及时送达 作者 | HongJie 链接 | javadoop.com/post/nio-and-aio 本文将介绍非阻塞 IO 和异步 IO,也就是 ...
- 聊聊对不同I/O模型的理解 (阻塞/非阻塞IO,同步/异步IO)
一.关于I/O模型的问题 最近通过对ucore操作系统的学习,让我打开了操作系统内核这一黑盒子,与之前所学知识结合起来,解答了长久以来困扰我的关于I/O的一些问题. 1. 为什么redis能以单工作线 ...
- python3 异步 非阻塞 IO多路复用 select poll epoll 使用
有许多封装好的异步非阻塞IO多路复用框架,底层在linux基于最新的epoll实现,为了更好的使用,了解其底层原理还是有必要的. 下面记录下分别基于Select/Poll/Epoll的echo ser ...
- 实例浅析epoll的水平触发和边缘触发,以及边缘触发为什么要使用非阻塞IO
一.基本概念 我们通俗一点讲: Level_triggered(水平触发):当被监控的文件描述符上有可读写事件发生时,epoll_wait()会通知处理程序去读写.如果这次没有把数据一次性全部读写完( ...
- Python异步非阻塞IO多路复用Select/Poll/Epoll使用
来源:http://www.haiyun.me/archives/1056.html 有许多封装好的异步非阻塞IO多路复用框架,底层在linux基于最新的epoll实现,为了更好的使用,了解其底层原理 ...
- 为何 epoll 的 ET 模式一定要设置为非阻塞IO
ET模式下每次write或read需要循环write或read直到返回EAGAIN错误.以读操作为例,这是因为ET模式只在socket描述符状态发生变化时才触发事件,如果不一次把socket内核缓冲区 ...
- Linux 阻塞和非阻塞IO 实验
目录 阻塞和非阻塞IO 阻塞和非阻塞简介 等待队列 轮询 Linux 驱动下的poll 操作函数 阻塞IO 实验 硬件原理图分析 实验程序编写 运行测试 非阻塞IO 实验 硬件原理图分析 实验程序编写 ...
- Linux之阻塞与非阻塞IO
目录 一.阻塞与非阻塞IO简介 1.阻塞IO 2.非阻塞IO 二.应用程序阻塞与非阻塞 1.阻塞 2.查询(非阻塞) ①select ②poll ③epoll 三.驱动程序阻塞与非阻塞 1.等待队列( ...
- Redis 笔记(12)— 单线程架构(非阻塞 IO、多路复用)和多个异步线程
Redis 使用了单线程架构.非阻塞 I/O .多路复用模型来实现高性能的内存数据库服务.Redis 是单线程的.那么为什么说是单线程呢? Redis 在 Reactor 模型内开发了事件处理器,这个 ...
最新文章
- 备份一张iPhone拍照写入exif中的orientation图片
- JSP学习笔记04-request
- spring IOC容器的扩展
- *30.什么是微内核
- 阿里巴巴DevOps实践指南 | 数字化转型下,DevOps的根本目标是什么?
- 怎么汇报一周开发工作情况_如何在没有经验的情况下获得第一份开发人员工作
- tinyxml初体验
- springmvc源码-参数解析
- 政府信息化与电子政务
- 整个AppData目录挪到D盘方法
- 淦!为什么到处都是广告!
- 推理时 cnn bn 折叠;基于KWS项目
- 员工奖金需要交税吗_定了!年终奖必须这样缴税!国家税务局终于明确。
- C#·Excel拉取日期格式的数据
- 0.1.3-01 合宙CORE-ESP32-C3制作1.3寸ST7789驱动的简单相册
- go开发虚拟串口服务器,vspd.go
- Mysql数据库使用规范
- 数值积分法(1)————欧拉法
- java 创建mdi窗体_Java制作MDI窗体源代码是什么?
- 什么是领域模型?什么是数据模型
热门文章
- 北京内推 | 启元实验室招聘视觉感知算法工程师(北京事业单位)
- 今晚直播 | ICML 2021论文解读:基于Cox-MLP模型的二阶段共形预测
- ICML 2020 | 基于类别描述的文本分类模型
- 【天池赛事】零基础入门语义分割-地表建筑物识别 Task5:模型训练与验证
- 打印Show Attend and Tell的损失函数
- PyTorch-torch.nn.AdaptiveAvgPool2d
- 从零学习SwinTransformer
- python知识点总结(有空就往里面添加)
- linux操作这样用视频,Linux下使用mencoder对视频进行操作
- 【Java报错】借助@PostConstruct解决使用@Component注解的类用@Resource注入Mapper接口为null的问题(原因解析+解决方法)