TCP多线程模型、IO模型(select、poll、epoll)

我要成为嵌入式高手之3月11日Linux高编第十九天!!
————————————————————————————

TCP并发模型

一、TCP多线程模型:

缺点:创建线程会带来资源开销,能够现的并发量比较有限

二、IO模型:

1、阻塞IO

        没有数据到来时,可以让任务挂起,节省CPU资源开销,提升系统效率

2、非阻塞IO

        fcntl

        程序未接收到数据时一直执行,效率很低

3、异步IO

        只能绑定一个文件描述符用来读取数据

4、多路复用IO

        多个IO用一个函数接口监测

        select

                1、select监听的集合中的文件描述符有上限限制

                2、select有内核层向用户层数据空间拷贝的过程,占用系统资源开销

                3、select必须轮询检测产生事件的文件描述符

                4、select只能工作在水平触发模式,无法工作在边沿触发(高速模式)

       /* 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 select(int nfds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout);

        功能:监听文件描述符中是否有文件描述符变成ready状态

        参数:

                nfds:最大文件描述符的值+1;

                readfds:读文件描述符的首地址

                writefds:写文件描述符的首地址

                exceptfds:其余文件描述符集合

                timeout:等待的市场,NULL一直等待

        返回值:成功返回文件描述符集合中文件描述符的个数,失败返回-1;

       void FD_CLR(int fd, fd_set *set);

        功能:将文件描述符fd从集合中清除

        int  FD_ISSET(int fd, fd_set *set);

        功能:判断文件描述符fd是否能在集合中

        void FD_SET(int fd, fd_set *set);

        功能:将文件描述符fd加入到集合中

        void FD_ZERO(fd_set *set);

        将文件描述符集合清0;

写端:

#include "head.h"int main(void)
{int fd = 0;char tmpbuff[4096] = {0};mkfifo("/tmp/myfifo", 0777);fd = open("/tmp/myfifo", O_WRONLY);if (-1 == fd){perror("fail to open");return -1;}while (1){gets(tmpbuff);write(fd, tmpbuff, strlen(tmpbuff));}close(fd);return 0;
}

读端:

#include "head.h"int main(void)
{int fd = 0;int flags = 0;char *pret = NULL;ssize_t nsize = 0;char tmpbuff[4096] = {0};fd_set rdfds;fd_set tmpfds;int ret = 0;mkfifo("/tmp/myfifo", 0664);fd = open("/tmp/myfifo", O_RDONLY);if (-1 == fd){perror("fail to open");return -1;}FD_ZERO(&rdfds);//将文件描述符集合清0FD_SET(fd, &rdfds);//将文件描述符fd加入到文件描述符集合中FD_SET(0, &rdfds);//将文件描述符0加入到文件描述符集合中while (1){tmpfds = rdfds;ret = select(fd+1, &tmpfds, NULL, NULL, NULL);if (-1 == ret){perror("fail to select");return -1;}if (FD_ISSET(fd, &tmpfds))//判断文件描述符fd是否还在文件描述符集合中{memset(tmpbuff, 0, sizeof(tmpbuff));read(fd, tmpbuff, sizeof(tmpbuff));printf("FIFO:%s\n", tmpbuff);}if (FD_ISSET(0, &tmpfds)){memset(tmpbuff, 0, sizeof(tmpbuff));gets(tmpbuff);printf("STDIN:%s\n", tmpbuff);}}close(fd);return 0;
}

 结果:

poll 

        1、poll监听的文件描述符没有上限的限制

        2、有内核层向用户层数据空间拷贝的过程,占用系统资源开销

        3、必须轮询检测产生事件的文件描述符

        4、只能工作在水平触发模式,无法工作在边沿触发(高速模式)

#include <poll.h>

int poll(struct pollfd *fds, nfds_t nfds, int timeout);

功能:监听文件描述符集合是否有事件发生

参数:

        fds:监听文件描述符集合数组的空间首地址

        nfds:监听文件描述符集合元素个数

        timeout:等待的时间(-1 一直等待)

返回值:成功返回产生事件的文件描述符的个数,失败返回-1;

           struct pollfd {
               int   fd;              /* file descriptor */(监听的文件描述符)
               short events;     /* requested events */(要监听的事件)
                        POLLIN:是否可读
                        POLLOUT:是否可写
               short revents;    /* returned events */(实际产生的事件)
           };

读端:

#include "head.h"int main(void)
{int fd = 0;int flags = 0;char *pret = NULL;ssize_t nsize = 0;char tmpbuff[4096] = {0};struct pollfd fds[2];int nready = 0;mkfifo("/tmp/myfifo", 0664);fd = open("/tmp/myfifo", O_RDONLY);if (-1 == fd){perror("fail to open");return -1;}fds[0].fd = fd;fds[0].events = POLLIN;fds[1].fd = 0;fds[1].events = POLLIN;while (1){nready = poll(fds, 2, -1);if (-1 == nready){perror("fail to poll");return -1;}if (fds[0].revents & POLLIN){memset(tmpbuff, 0, sizeof(tmpbuff));read(fd, tmpbuff, sizeof(tmpbuff));printf("FIFO:%s\n", tmpbuff);}if (fds[1].revents & POLLIN){memset(tmpbuff, 0, sizeof(tmpbuff));gets(tmpbuff);printf("STDIN:%s\n", tmpbuff);}}close(fd);
}

写端:

#include "head.h"int main(void)
{int fd = 0;char tmpbuff[4096] = {0};mkfifo("/tmp/myfifo", 0664);fd = open("/tmp/myfifo", O_WRONLY);if (-1 == fd){perror("fail to open");return -1;}while (1){gets(tmpbuff);write(fd, tmpbuff, strlen(tmpbuff));}close(fd);return 0;
}

结果:

 epoll

1、epoll_create

#include <sys/epoll.h>

int epoll_create(int size);

功能:创建一张内核事件表

参数:size:事件的个数

返回值:成功返回文件描述符,失败返回-1;

2、epoll_ctl

#include <sys/epoll.h>

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

功能:维护epoll事件表

参数:

        epfd:事件表的文件描述符

        op:

                EPOLL_CTL_ADD添加事件

                EPOLL_CTL_MOD修改事件

                EPOLL_CTL_DEL删除事件

        fd:操作的文件描述符

        event:事件对应的事件

           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 */
           };

返回值:成功0,失败-1;

events:

data:要操作的文件的文件描述符 

3、epoll_wait

#include <sys/epoll.h>

int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout);

功能:监听事件表中的事件

参数:

        epfd:事件表的文件描述符

        events:存放实际产生事件的数组空间首地址

        maxevents:最多存放事件的个数

        timeout:设定监听的时间(超过该时间不再监听)-1一直监听直到有事件发生

返回值:

        成功返回实际产生事件的文件描述符的个数

        时间到达还没有事件产生返回0

        失败返回-1

read.c

#include "head.h"int main(void)
{int fd = 0;int epfd = 0;struct epoll_event env;//epoll_ctl需要的事件的结构体int nready = 0;struct epoll_event retenv[2];int i = 0;ssize_t nsize = 0;char *pret = NULL;char tmpbuff[4096] = {0};mkfifo("/tmp/myfifo", 0664);fd = open("/tmp/myfifo", O_RDONLY);if (-1 == fd){perror("fail to open");return -1;}/*创建一张2个事件的内核事件表*/epfd = epoll_create(2);if (epfd == -1){perror("fail to create");return -1;}/*设置事件结构体的属性*/env.events = EPOLLIN;env.data.fd = fd;/*操作事件*/epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &env);env.events = EPOLLIN;env.data.fd = 0;epoll_ctl(epfd, EPOLL_CTL_ADD, 0, &env);while (1){/*监听事件表中的事件*/nready = epoll_wait(epfd, retenv, 2, -1);//第二个参数是存放实际产生事件的结构体, 最多存放的个数, 设置监听时间,-1一直监听直到有事件发生if (-1 == nready){perror("fail to nready");return -1;}for (i = 0; i < nready; ++i){if (retenv[i].data.fd == 0)//判断要操作的流是否为从终端输入{memset(tmpbuff, 0, sizeof(tmpbuff));gets(tmpbuff);printf("STDIN: %s\n", tmpbuff);}if (retenv[i].data.fd == fd){memset(tmpbuff, 0, sizeof(tmpbuff));read(fd, tmpbuff, sizeof(tmpbuff));printf("FIFO: %s\n", tmpbuff);}}}close(fd);return 0;
}

write.c

#include "head.h"int main(void)
{int fd = 0;char tmpbuff[4096] = {0};mkfifo("/tmp/myfifo", 0664);fd = open("/tmp/myfifo", O_WRONLY);if (-1 == fd){perror("fail to open");return -1;}while (1){gets(tmpbuff);write(fd, tmpbuff, strlen(tmpbuff));}close(fd);return 0;
}

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【PHP】PHP通过串口与硬件通讯,向硬件设备发送数据并接收硬件返回的数据

一、前言 之前写过两篇PHP实现与硬件串口交互的文章&#xff0c;一篇是【PHP】PHP实现与硬件串口交互&#xff0c;接收硬件发送的实时数据&#xff08;上&#xff09;_php串口通信-CSDN博客&#xff0c;另一篇是【PHP】PHP实现与硬件串口交互&#xff0c;向硬件设备发送指令数…

HarmonyOS NEXT应用开发之图片缩放效果实现

腾讯T10级高工技术&#xff0c;安卓全套VIP课程全网免费送&#xff1a;https://docs.qq.com/doc/DSG1vYnRxSElnU3hE 学习鸿蒙开发势在必行。鸿蒙开发可参考学习文档&#xff1a;https://qr21.cn/FV7h05 介绍 图片预览在应用开发中是一种常见场景&#xff0c;在诸如QQ、微信、…

Facebook商城号为什么被封?如何防封?

由于Facebook商城的高利润空间&#xff0c;越来越多的跨境电商商家注意到它的存在。Facebook作为全球最大、用户量最大的社媒平台&#xff0c;同时也孕育了一个巨大的商业生态&#xff0c;包括广告投放、商城交易等。依托背后的大流量&#xff0c;Facebook商城起号较快&#xf…

GPU,一统天下

三十年前&#xff0c;CPU 和其他专用处理器几乎处理所有计算任务。那个时代的显卡有助于加快 Windows 和应用程序中 2D 形状的绘制速度&#xff0c;但没有其他用途。 快进到今天&#xff0c;GPU 已经成为业界最具主导地位的芯片之一。 但具有讽刺意味的是&#xff0c;图形芯片…

ETCD入门

目录 一、简介 1. etcd是什么 2. 特点 3. 使用场景 4. 关键字 5. 工作原理 6. 获取 二、安装 1. etcd安装前的介绍 2. 安装 3. 启动 4. 创建一个etcd服务 三、ETCD的使用 一、简介 1. etcd是什么 etcd是CoreOS团队于2013年6月发起的开源项目&#xff0c;它的目标是…

Retrofit

1.导入依赖 //Retrofit 核心库implementation("com.squareup.retrofit2:retrofit:2.9.0")//响应数据自动序列化//JSONimplementation("com.squareup.retrofit2:converter-gson:2.9.0")//String类型implementation("com.squareup.retrofit2:converter…

Python速度大比拼:与主流编程语言的速度对决

在评估用于具体业务的编程语言时&#xff0c;经常考虑的一个关键指标之一是执行速度。Python以其简单性和可读性而闻名&#xff0c;但有时却因其性能而受到质疑。在这个领域&#xff0c;我们需要深入比较分析Python在执行速度方面与其他流行的编程语言相比的情况。 程语言执行速…

网络编程(3/6)

使用C语言完成数据库的增删改 #include<myhead.h> int do_add(sqlite3 *ppDb) {int numb;char name[50];int salary;printf("请输入员工信息&#xff1a;工号、姓名、薪水\n");scanf("%d %s %d",&numb,name,&salary);char sql[128];char *e…

Nginx七层的负载均衡使用keepalived实现高可用

目录 一、环境准备 二、两台nginx服务器作为代理服务器,配置nginx的负载均衡 三、Keepalived实现调度器 Proxy-master 与 Proxy-slave机器同时操作安装 备份配置文件 编辑主Proxy-master的配置文件 编辑从 Proxy-slaver的配置文件 四、 启动KeepAlived&#xff08;主备…

CleanMyMac X4.15中文完整免费版下载

CleanMyMac X是一款功能全面的Mac管理软件&#xff0c;它能帮助用户清理无用的文件&#xff0c;监控系统健康&#xff0c;管理启动项&#xff0c;甚至还能移除恶意软件&#xff0c;确保你的Mac保持最佳状态。其直观的界面设计使得新手用户也能轻松上手&#xff0c;一键扫描和清…

【算法】一类支持向量机OC-SVM

【算法】一类支持向量机OC-SVM 前言一类支持向量机OC-SVM 概念介绍示例编写数据集创建实现一类支持向量机OC-SVM完整的示例输出 前言 由于之前毕设期间主要的工具就是支持向量机&#xff0c;从基础的回归和分类到后来的优化&#xff0c;在接触到支持向量机还有一类支持向量机的…

脚手架cli快速创建Vue2/Vue3项目

前言&#xff1a; 本文的nodejs版本是14.21.3 第一步 进入cmd窗口 1、全局安装webpack npm install webpack-g&#xff0c; npm install webpack-g 第二步 2、全局安装vue脚手架 npm install -g vue/cli 第三步 3、初始化vue项目 &#xff08;vue脚手架使用webpack模…

宝妈做什么兼职副业好?适合她们的有哪些?执行力才是关键

现在的宝妈&#xff0c;生完孩子以后&#xff0c;尤其是宝宝上幼儿园之前&#xff0c;为了照顾宝宝&#xff0c;不能去外面上班&#xff0c;所以很多妈妈都为孩子做出了很大的牺牲&#xff0c;但同时又要承担着家庭经济的压力&#xff0c;尤其是现在注重个性独立的时代&#xf…

基于微信小程序的电子商城购物平台的设计与实现(论文+源码)_kaic

摘 要 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;电子商城购物平台小程序被用户普遍使用&#xff0c;为方便…

图及图的存储

目录 1.图的相关概念 2.图的存储 2.1.直接存法 1.查询是否存在某条边 2.遍历一个点的所有出边 3..遍历整个图 应用 2.2.邻接矩阵 1.查询是否存在某条边 2.遍历一个点的所有出边 3..遍历整个图 应用 2.3.邻接表 1.查询是否存在某条边 2.遍历一个点的所有出边 3..遍…

RabbitMQ应用场景

1、异步处理 假设想象一下我们做一个商城项目&#xff0c;在用户支付模块中&#xff0c;可能会涉及到其它业务&#xff0c;比如&#xff1a;积分折扣、消费券、短信验证等功能。我们传统的执行步骤是逐步执行&#xff0c;也就是说当用户点击支付 ----> 积分折扣 ----> 消…

Project_Euler-10 题解

Project_Euler-10 题解 题目 思路 没有思路&#xff0c;一个线性筛秒了,只不过最近没发博客有点手生哈哈哈哈哈。 代码 /*************************************************************************> Author: Royi > Mail: royi990001gmail.com > From: > Lan…

2014-2023年上市银行华证ESG评级数据/银行ESG评级数据

2014-2023年上市银行华证ESG评级数据/银行ESG评级数据 1、时间&#xff1a;2014-2023年 2、指标&#xff1a;证券代码、证券简称、华证ESG评级 3、来源&#xff1a;原始数据整理自wind 4、范围&#xff1a;42家银行&#xff1a; 苏农银行、中信银行、贵阳银行、中国银行、…

力扣---接雨水---单调队列+动态规划+双指针

题目&#xff1a; 单调队列思想&#xff1a; 没有思路的小伙伴可以先把这个想清楚哦&#xff1a;力扣hot10---大根堆双端队列-CSDN博客 从上面的图就可以发现&#xff0c;如果柱子呈递减序列&#xff0c;那么不会接到雨水&#xff0c;只要有一个小凸起柱子&#xff0c;那么这个…

智慧城市的前景:数字孪生技术在智慧城市中的应用前景

目录 一、引言 二、数字孪生技术及其在智慧城市中的应用概述 三、数字孪生技术在智慧城市中的应用前景 1、城市规划与仿真模拟 2、智能交通与出行服务 3、智慧环保与可持续发展 4、智慧公共服务与社会治理 5、智慧能源与绿色建筑 四、数字孪生技术在智慧城市中的挑战与…