IO多路复用简介和代码实例(select函数)

接上篇

阻塞IO、非阻塞IO、IO多路复用和信号驱动IO简介-CSDN博客文章浏览阅读95次。阻塞IO、非阻塞IO、IO多路复用和信号驱动IO简介https://blog.csdn.net/CSDN_DU666666/article/details/139598410?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22139598410%22%2C%22source%22%3A%22CSDN_DU666666%22%7D

基本思想:

        构造一个关于文件描述符的表,将所以要监视的文件描述符都放在这个表里

        将这个表传给一个函数 (select poll epoll),这个函数默认也是阻塞的

        当监视的文件描述中有一个或多个文件描述符准备就绪的时候

        函数会立即返回,并告诉调用者哪些文件描述符已经就绪了

        我们已经知道哪些文件描述符就绪了,再去执行对应的io操作,就不会阻塞了

select函数

功能:
	实现多路IO复用
头文件:
	#include <sys/select.h>
函数原型:
	int select(int nfds, fd_set *readfds, fd_set *writefds,
                fd_set *exceptfds, struct timeval *timeout);
参数:
	nfds:		要监视的最大文件描述符+1
	readfds:	要监视的读文件描述符集合 不关心可以传NULL
	writefds:	要监视的写文件描述符集合 不关心可以传NULL
	exceptfds:	要监视的异常文件描述符集合 不关心可以传NULL
	timeout:	超时时间 如果设置成NULL 会一直阻塞 直到有文件描述符就绪
返回值:
	成功 就绪的文件描述符的个数
	超时 0
	失败 -1 重置错误码 

注意事项:
	1.select只能监视小于FD_SETSIZE(1024)的文件描述符
	2.select返回时会将没有就绪的文件描述符在集合中擦除
		所以循环中使用select时 每次需要重置集合
	3.我们一般只关心读文件文件描述符集合 其他两个置NULL即可
	
	void FD_CLR(int fd, fd_set *set);	//将文件描述符在集合中删除
	int  FD_ISSET(int fd, fd_set *set);	//判断文件描述符是否还在集合中
										// 返回0 表示不在了 非0 表示在
	void FD_SET(int fd, fd_set *set);	//向集合中添加一个文件描述符
	void FD_ZERO(fd_set *set);			//清空集合

service.c

首先创建三个管道文件

指令:mkfifo fifo1  

          mkfifo fifo2

          mkfifo fifo3

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>

int main(int argc, const char *argv[]){
    int fd1 = open("fifo1", O_RDONLY);
    int fd2 = open("fifo2", O_RDONLY);
    int fd3 = open("fifo3", O_RDONLY);
    char buff[128] = {0};

    //创建文件描述符集合
    fd_set readfds;//母本
    FD_ZERO(&readfds);
    fd_set readfds_temp;//副本 用来给select每次擦除用
    FD_ZERO(&readfds_temp);

    int max_fd = 0;//用来记录最大的文件描述符
    //将要监视的文件描述符添加到集合中
    FD_SET(fd1, &readfds);
    max_fd = max_fd>fd1 ? max_fd : fd1;
    FD_SET(fd2, &readfds);
    max_fd = max_fd>fd2 ? max_fd : fd2;
    FD_SET(fd3, &readfds);
    max_fd = max_fd>fd3 ? max_fd : fd3;
#if 0
    //基础版
    while(1){
        //select返回时会将没有就绪的文件描述符在集合中擦除
		//所以循环中使用select时 每次需要重置集合
        readfds_temp = readfds;
        if(-1 == select(max_fd+1, &readfds_temp, NULL, NULL, NULL)){
            perror("select error");
        }
        //程序执行到这儿 说明有文件描述符就绪了
        //我们需要判断谁就绪了
        if(FD_ISSET(fd1, &readfds_temp)){
            memset(buff, 0, 128);
            read(fd1, buff, 128);
            printf("fifo1:[%s]\n", buff);
        }
        if(FD_ISSET(fd2, &readfds_temp)){
            memset(buff, 0, 128);
            read(fd2, buff, 128);
            printf("fifo2:[%s]\n", buff);
        }
        if(FD_ISSET(fd3, &readfds_temp)){
            memset(buff, 0, 128);
            read(fd3, buff, 128);
            printf("fifo3:[%s]\n", buff);
        }
    }
#endif

#if 1
//进阶版
    //基础版
    int ret = 0;
    int i = 0;
    while(1){
        readfds_temp = readfds;
        if(-1 == (ret = select(max_fd+1, &readfds_temp, NULL, NULL, NULL))){
            perror("select error");
        }
        //遍历文件描述符集合 谁还在里面说明谁就绪
        for(i = 3; i < max_fd+1 && ret != 0; i++){
            if(FD_ISSET(i, &readfds_temp)){
                memset(buff, 0, 128);
                read(i, buff, 128);
                printf("buff[%d-3]:[%s]\n",i, buff);
                ret--;//此处的ret--是为了提高效率的
            }
        }
    }
#endif

    close(fd1);
    close(fd2);
    close(fd3);

    return 0;
}

client.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

int main(int argc, const char *argv[]){
  int fd = open("fifo1", O_WRONLY);//fifo2 fiof3
    char buff[128] = {0};

    while(1){
        memset(buff, 0, 128);
             printf("请输入:");
        fgets(buff, 128, stdin);
        buff[strlen(buff)-1] = '\0';
        write(fd, buff, 128);
    }
    close(fd);

    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/706679.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】易错点——/etc/passwd ; /etc/shadow;ifconfig;route;chmod;ps;mv

/etc/passwd ; /etc/shadow /etc/passwd&#xff1a; 用户账户的详细信息在此文件中更新。 用户名&#xff1a;密码&#xff1a;用户 ID&#xff1a;群组 ID&#xff1a;用户 ID 信息&#xff1a;用户的家目录&#xff1a; Shell /etc/shadow&#xff1a; 用户账户密码在此文…

ssm160基于Java技术的会员制度管理的商品营销系统的设计与实现+vue

商品营销系统计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本商品营销系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理…

【C++取经之路】继承

目录 继承的概念及定义 单继承的格式 继承方式和访问限定符 继承后子类访问基类成员的权限 基类和派生类对象赋值转换 切片 继承中的作用域 引申&#xff1a;重载和隐藏的区别 派生类的默认成员函数 继承与友元 继承与静态成员 如何实现一个不能被继承的类 复杂的…

【SkiaSharp绘图03】SKPaint详解(一)BlendMode混合模式、ColorFilter颜色滤镜

文章目录 SKPaintSKPaint属性BlendMode获取或设置混合模式SKBlendMode 枚举成员效果预览 Color/ColorF获取或设置前景色ColorFilter 颜色滤镜CreateBlendMode 混合模式CreateColorMatrix 颜色转换CreateCompose 组合滤镜CreateHighContrast 高对比度滤镜CreateLighting 照明滤镜…

Java最新面试题(全网最全、最细、附答案)

一、Java基础 1、基础概念与常识Java 语言有哪些特点? 简单易学&#xff08;语法简单&#xff0c;上手容易&#xff09;&#xff1b;面向对象&#xff08;封装&#xff0c;继承&#xff0c;多态&#xff09;&#xff1b;平台无关性&#xff08; Java 虚拟机实现平台无关性&a…

千万级流量冲击下,如何保证极致性能

1 简要介绍 随着互联网的快速发展&#xff0c;网络应用的流量规模不断攀升&#xff0c;特别是在电商大促、明星直播、重大赛事、头条热搜等热点事件中&#xff0c;秒级100w请求成为了常态。在这样的流量冲击下&#xff0c;如何确保系统稳定、高效地处理每一个请求&#xff0c;为…

抖某音号解封释放实名

##抖音账号封禁后如何解封呢 我相信&#xff0c;做过抖音&#xff0c;或者正在做抖音的朋友&#xff0c;都曾面临一种尴尬至极的局面&#xff0c;辛辛苦苦做起来的账号&#xff0c;或者刚刚准备好的账号&#xff0c;在一时之间&#xff0c;竟然被抖音官方封禁了&#xff01; 实…

ubuntu下使用cmake编译opencv4.8.0+ffmpeg4.2.2+cuda11.1

1.源码下载 &#xff08;1&#xff09;下载ffmpeg4.2.2、opencv4.8.0源码&#xff0c;这里提供一个百度网盘地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1pBksr0_RtKL0cM6Gsf2MGA?pwdcyai 提取码&#xff1a;cyai &#xff08;2&#xff09;解压所有文件 例…

小而美的算法技巧:前缀和数组

小而美的算法技巧&#xff1a;前缀和数组 类似动态规划。 class NumArray {private int[] preSum;public NumArray(int[] nums) {preSumnew int[nums.length1];//preSum[0]的前缀和为0for(int i1;i<preSum.length;i){preSum[i]nums[i-1]preSum[i-1];//先计算累加和}}publi…

Git进阶使用(图文详解)

文章目录 Git概述Git基础指令Git进阶使用一、Git分支1.主干分支2.其他分支2.1创建分支2.2查看分支1. 查看本地分支2. 查看远程分支3. 查看本地和远程分支4. 显示分支的详细信息5. 查看已合并和未合并的分支 2.3切换分支1. 切换到已有的本地分支2. 创建并切换到新分支3. 切换到远…

毕业年薪20w起!25届最近5年南京信息工程大学自动化考研院校分析

南京信息工程大学 目录 一、学校学院专业简介 二、考试科目指定教材 三、近4年考研分数情况 四、近4年招生录取情况 五、最新一年分数段图表 六、历年真题PDF 七、初试大纲复试大纲 八、学费&奖学金&就业方向 一、学校学院专业简介 二、考试科目指定教材 1、…

掌握WhoisAPI,提升域名管理的效率

在互联网时代&#xff0c;域名管理是网站运营中非常重要的一环。通过域名&#xff0c;我们能够轻松访问和识别不同的网站。然而&#xff0c;域名的注册和管理也是一项复杂的任务&#xff0c;特别是对于大规模拥有许多域名的企业来说。为了提升域名管理的效率&#xff0c;我们可…

边缘计算网关在智慧厕所远程监测与管理的应用

随着智慧城市建设的不断深入&#xff0c;城市公共设施的智慧化管理成为了提升城市品质和居民生活质量的关键建设。公厕作为城市基础设施的重要组成部分&#xff0c;其管理效率和卫生状况直接影响着市民的日常生活体验。在公厕设施建设背景下&#xff0c;边缘计算网关技术的应用…

ansible离线安装docker

docker简介&#xff1a; Docker 是一个开源的应用容器引擎&#xff0c;它允许开发者打包他们的应用以及应用的运行环境到一个可移植的容器中。这个容器可以在任何支持Docker的机器上运行&#xff0c;确保了应用在不同环境中的一致性。 网上有很多在线ansible安装docker的&…

Base64编码方式的介绍及其编码解码

一、Base64是什么 Base64是一种用于将二进制数据编码为ASCII字符的编码方式&#xff0c;主要目的是为了能够在文本环境中传输和存储二进制数据。这种编码方式广泛应用于电子邮件、HTTP协议和其他需要传输或存储二进制数据的地方。 二、发明Base64编码的原因 Base64编码的发明解…

猫狗识别(超详细版)(py代码)

猫狗识别&#xff08;一&#xff09; 二、视频识别 用OpenCV和Tkinter构建的视频识别猫狗的应用程序。它允许用户从文件对话框中选择一个视频文件&#xff0c;然后在Tkinter窗口中播放视频&#xff0c;并使用Haar级联分类器实时检测视频中的猫和狗。 1.导入所需的库&#xff…

QT--DAY1

不使用图形化界面实现一个登陆界面 #include "widget.h"Widget::Widget(QWidget *parent): QWidget(parent) {//设置窗口标题this->setWindowTitle("登录界面");//设置窗口大小this->resize(535,410);//固定窗口大小this->setFixedSize(535,410)…

北京多商入驻app开发项目的主要优势及功能

多商入驻app开发项目的定义 随着电子支付技术的不断成熟&#xff0c;全国各地的消费者通过网络在线上购物的频率越来越高&#xff0c;为此&#xff0c;多商入驻app开发项目应用而生。各商家也纷纷开始申请入驻商城平台&#xff0c;开设自己的店铺。 图片来源&#xff1a;unspl…

MAVEN-SNAPSHOT和RELEASE

一、快照版本SNAPSHOT和发布版本RELEASE区别 快照版本SNAPSHOT和发布版本RELEASE区别-CSDN博客 在使⽤maven过程中&#xff0c;我们在开发阶段经常性的会有很多公共库处于不稳定状态&#xff0c;随时需要修改并发布&#xff0c;可能⼀天就要发布⼀次&#xff0c;遇到bug时&am…

网络编程(三)UDP TFTP协议

文章目录 一、 UDP&#xff08;一&#xff09;概述&#xff08;二&#xff09;流程 二、收发函数&#xff08;一&#xff09;recvfrom&#xff08;二&#xff09;sendto 三、实现一个简单的udp服务端和客户端四、实现tftp客户端协议 一、 UDP &#xff08;一&#xff09;概述 …