当前位置: 首页 > news >正文

嵌入式系统学习Day31(多路IO复用)

IO模型
1、阻塞IO
2、非阻塞IO EAGAIN 忙等待 errno
3、信号驱动IOSIGIO 用的相对少(了解)
4、并行模型进程,线程
5, IO多路复用 select、poll、epoll
1、阻塞IO ===》最常用 默认设置
2、非阻塞IO ===》在阻塞IO的基础上调整其为不再阻塞等待。
在程序执行阶段调整文件的执行方式为非阻塞:
===》fcntl(===>动态调整文件的阻塞属性
#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, .. /* arg */ );
功能:修改指定文件的属性信息。
参数:fd 要调整的文件描述符
cmd 要调整的文件属性宏名称
可变长的属性值参数。
返回值:成功不一定,看cmd
失败-1;

select
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
void FD_CLR(int fd, fd_set *set); 
int FD_ISSET(int fd, fd_set *set);
void FD_SET(int fd, fd_set *set); 
void FD_ZERO(fd_set *set);
select的调用一般要注意几点:
readfds等是指针结果参数,会被函数修改,所以一般会另外定义一个allread_fdset,保持全部要监听读的句柄,将它的拷贝传递给select函数,返回可读的句柄集合,类型fdset
支持赋值运算符=;

要注意计算nfds,当新增监听句柄时比较容易修改,当减少监听句柄时较麻烦些,如果要精确修改需要遍历或者采用最大堆等数据结构维护这个句柄集,以方便的找到第二大的
句柄,或者干脆在减少监听句柄时不管nfds ;
③ timeout如果为NULL表示阻塞等,如果timeout指向的时间为O,表示非阻塞,否则表示select的超时时间;
④ select返回-1表示错误,返回0表示超时时间到没有监听到的事件发生,返回正数表示监听到的所有事件数(包括可读,可写,异常),通常在处理事件时
会利用这个返回值来提高效率,避免不必要的事件触发检查。(比如总共只有一个事件,已经在可读集合中处理了一个事件,则可写和异常就没必要再去遍历句柄集
判断是否发生事件了);
③ Linux的实现中select返回时会将timeout修改为剩余时间,所以重复使用timeout需要注意。
select的缺点在于:
① 由于描述符集合set的限制,每个set最多只能监听FD_SETSIZE(在Linux上是1024)个句柄(不同机器可能不一样);
② 返回的可读集合是个fdset类型,需要对所有的监听读句柄一一进行FD_ISSET的测试来判断是否可读;

nfds的存在就是为了解决select的效率问题(select遍历nfds个文件描述符,判断每个描述符是否是自己关心的,对关心的描述符判断是否发生事件)。但是解决不彻底,比如如
果只监听0和1000两个句柄,select需要遍历1001个句柄来检查事件。

1.阻塞模型blockIO

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[])
{int ret = mkfifo("myfifo", 0666);if (-1 == ret){if (EEXIST == errno){}else{perror("mkfifo error\n");return 1;}}int fd = open("myfifo", O_WRONLY);if (-1 == fd){perror("open error\n");return 1;}while (1){char buf[512] = "hello,this is fifo tested...\n";write(fd, buf, strlen(buf) + 1);sleep(3);}close(fd);return 0;
}
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[])
{int ret = mkfifo("myfifo", 0666);if (-1 == ret){if (EEXIST == errno){}else{perror("mkfifo error\n");return 1;}}int fd = open("myfifo", O_RDONLY);if (-1 == fd){perror("open error\n");return 1;}while (1){char buf[512] = {0};read(fd, buf, sizeof(buf));printf("fifo :%s\n", buf);bzero(buf,sizeof(buf));fgets(buf,sizeof(buf),stdin);printf("terminal:%s",buf);fflush(stdout);}close(fd);// remove("myfifo");return 0;
}

2.非阻塞模型nonblockIO

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[])
{int ret = mkfifo("myfifo", 0666);if (-1 == ret){if (EEXIST == errno){}else{perror("mkfifo error\n");return 1;}}int fd = open("myfifo", O_WRONLY);if (-1 == fd){perror("open error\n");return 1;}while (1){char buf[512] = "hello,this is fifo tested...\n";write(fd, buf, strlen(buf) + 1);sleep(3);}close(fd);return 0;
}
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[])
{int ret = mkfifo("myfifo", 0666);if (-1 == ret){if (EEXIST == errno){}else{perror("mkfifo error\n");return 1;}}int fd = open("myfifo", O_RDONLY);if (-1 == fd){perror("open error\n");return 1;}int flag = fcntl(fd, F_GETFL, 0);fcntl(fd, F_SETFL, flag | O_NONBLOCK);flag = fcntl(fileno(stdin), F_GETFL, 0);fcntl(0, F_SETFL, flag | O_NONBLOCK);while (1){char buf[512] = {0};if (read(fd, buf, sizeof(buf)) > 0){printf("fifo :%s\n", buf);}bzero(buf, sizeof(buf));if (fgets(buf, sizeof(buf), stdin)){printf("terminal:%s", buf);fflush(stdout);}}close(fd);// remove("myfifo");return 0;
}

3.信号驱动IO

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[])
{int ret = mkfifo("myfifo", 0666);if (-1 == ret){if (EEXIST == errno){}else{perror("mkfifo error\n");return 1;}}int fd = open("myfifo", O_WRONLY);if (-1 == fd){perror("open error\n");return 1;}while (1){char buf[512] = "hello,this is fifo tested...\n";write(fd, buf, strlen(buf) + 1);sleep(3);}close(fd);return 0;
}
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int fd;
void myhandle(int num)
{char buf[512] = {0};read(fd, buf, sizeof(buf));printf("fifo :%s\n", buf);
}
int main(int argc, char *argv[])
{signal(SIGIO, myhandle);int ret = mkfifo("myfifo", 0666);if (-1 == ret){if (EEXIST == errno){}else{perror("mkfifo error\n");return 1;}}fd = open("myfifo", O_RDONLY);if (-1 == fd){perror("open error\n");return 1;}int flag = fcntl(fd, F_GETFL);fcntl(fd, F_SETFL, flag | O_ASYNC);fcntl(fd, F_SETOWN, getpid());while (1){char buf[512] = {0};bzero(buf, sizeof(buf));fgets(buf, sizeof(buf), stdin);printf("terminal:%s", buf);fflush(stdout);}close(fd);// remove("myfifo");return 0;
}

4.IO多路复用

1.select

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[])
{int ret = mkfifo("myfifo", 0666);if (-1 == ret){if (EEXIST == errno){}else{perror("mkfifo error\n");return 1;}}int fd = open("myfifo", O_WRONLY);if (-1 == fd){perror("open error\n");return 1;}while (1){char buf[512] = "hello,this is fifo tested...\n";write(fd, buf, strlen(buf) + 1);sleep(3);}close(fd);return 0;
}
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
/* According to POSIX.1-2001, POSIX.1-2008 */
#include <sys/select.h>/* According to earlier standards */
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>int main(int argc, char *argv[])
{int ret = mkfifo("myfifo", 0666);if (-1 == ret){if (EEXIST == errno){}else{perror("mkfifo error\n");return 1;}}int fd = open("myfifo", O_RDONLY);if (-1 == fd){perror("open error\n");return 1;}// 1 create setfd_set rd_set,tmp_set;  // read setFD_ZERO(&rd_set);FD_ZERO(&tmp_set);// 2 add fdFD_SET(0, &tmp_set);FD_SET(fd, &tmp_set);while (1){rd_set = tmp_set;select(fd + 1, &rd_set, NULL, NULL, NULL);char buf[512] = {0};if (FD_ISSET(fd,&rd_set)){read(fd, buf, sizeof(buf));printf("fifo :%s\n", buf);}if (FD_ISSET(0, &rd_set)){bzero(buf, sizeof(buf));fgets(buf, sizeof(buf), stdin);printf("terminal:%s", buf);fflush(stdout);}}close(fd);// remove("myfifo");return 0;
}

2.epoll

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[])
{int ret = mkfifo("myfifo", 0666);if (-1 == ret){if (EEXIST == errno){}else{perror("mkfifo error\n");return 1;}}int fd = open("myfifo", O_WRONLY);if (-1 == fd){perror("open error\n");return 1;}while (1){char buf[512] = "hello,this is fifo tested...\n";write(fd, buf, strlen(buf) + 1);sleep(3);}close(fd);return 0;
}
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>int add_fd(int epfd, int fd)
{struct epoll_event ev;ev.events = EPOLLIN;ev.data.fd = fd;int ret = epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev);if (-1 == ret){perror("add fd");return 1;}
}
int main(int argc, char *argv[])
{int ret = mkfifo("myfifo", 0666);if (-1 == ret){if (EEXIST == errno){}else{perror("mkfifo error\n");return 1;}}int fd = open("myfifo", O_RDONLY);if (-1 == fd){perror("open error\n");return 1;}struct epoll_event rev[2];// 1 create setint epfd = epoll_create(2);if (-1 == epfd){perror("epoll_create");return 1;}// 2 add fdadd_fd(epfd, 0);add_fd(epfd, fd);while (1){char buf[512] = {0};int ep_ret = epoll_wait(epfd, rev, 2, -1);for (int i = 0; i < ep_ret; i++){if (rev[i].data.fd == fd){read(fd, buf, sizeof(buf));printf("fifo :%s\n", buf);}else if (0 == rev[i].data.fd){bzero(buf, sizeof(buf));fgets(buf, sizeof(buf), stdin);printf("terminal:%s", buf);fflush(stdout);}}}close(fd);// remove("myfifo");return 0;
}


文章转载自:

http://FJEY9QC4.tbpjc.cn
http://SqfGYjS4.tbpjc.cn
http://EDdaD7BP.tbpjc.cn
http://JjVCpSrg.tbpjc.cn
http://gCVIC7yV.tbpjc.cn
http://Y1Q8iZcw.tbpjc.cn
http://f4bj5CHM.tbpjc.cn
http://1PBYVXPG.tbpjc.cn
http://PWA62tfW.tbpjc.cn
http://RACBjlsI.tbpjc.cn
http://5SJfKtpH.tbpjc.cn
http://okyX2Deo.tbpjc.cn
http://RYnt3YAh.tbpjc.cn
http://QerqNZ71.tbpjc.cn
http://j59vCVmP.tbpjc.cn
http://3SQNbYf1.tbpjc.cn
http://frVCcN65.tbpjc.cn
http://zrYJ1LIL.tbpjc.cn
http://KzdEOnsp.tbpjc.cn
http://qqhyT6VT.tbpjc.cn
http://sRwhgAAM.tbpjc.cn
http://n3kur4gO.tbpjc.cn
http://ytQ9v65p.tbpjc.cn
http://Ovq9Fv4x.tbpjc.cn
http://6FsG25Fq.tbpjc.cn
http://qHzOsxmD.tbpjc.cn
http://JPoEFWgS.tbpjc.cn
http://dYqXG71I.tbpjc.cn
http://uVMzR9jT.tbpjc.cn
http://tatf2xmM.tbpjc.cn
http://www.dtcms.com/a/369751.html

相关文章:

  • vim 常用快捷键汇总
  • 1.进程与线程:区别、通信方式、同步方式
  • The Algorithmic Foundations of Differential Privacy - 4
  • 各种背包问题简述
  • Python反向迭代完全指南:从基础到高性能系统设计
  • CRYPT32!ASN1Dec_SignedDataWithBlobs函数分析之CRYPT32!ASN1Dec_AttributesNC的作用是得到三个证书
  • vcenter管理的4台安装了esxi机器组成的HA,故障后自恢复理解
  • 智慧医疗——解读医院智慧管理分级评估标准体系【附全文阅读】
  • C++ map和set
  • js闭包问题
  • 【教学类-36-10】20240905(通义万相)-A4各种大小的鱼制作“吐泡泡的鱼”01版
  • 【工具变量】上市公司企业海外业务收入数据集(2003-2024年)
  • 从技术选型到现场配置:DDC 楼宇自控系统全流程落地方案(2025 版)
  • 阿里云ecs 2h2g 实际可用内存不足的情况
  • 【React】性能提升方案:Reat.memo, useMemo,useCallback用法详解
  • 文心快码已支持Kimi-K2-0905模型
  • 6.ImGui-颜色(色板)
  • biocmanager安装 库 老是提示网络连接错误 才尝试各种办法
  • 雨后阳光为何更强烈?
  • 数据加盐处理(密码加盐)
  • 本地 Ai 离线视频去水印字幕!支持字幕、动静态水印去除!
  • 文件不展示Eslint的报错红色
  • vggt代码详解
  • 使用海康威视 SDK 实现软触发拍照(C语言完整示例 + 中文注释)
  • 本科论文抽检档案整理:Python批量文件查找、打包、改名
  • 【Day 22】94.二叉树的中序遍历 104.二叉树的最大深度 226.翻转二叉树 101.对称二叉树
  • swing笔记
  • IPD模式下跨部门团队管理
  • Transformer核心—自注意力机制
  • 可搜索且多选的下拉式列表