Day 9. TCP并发模型、select、poll、epoll

TCP并发模型

1.TCP多线程模型:

缺点:

1)创建线程会带来资源开销,能够实现

2.IO模型:

1)阻塞IO:没有数据到来时,可以让任务故挂起,节省CPU资源开销,提高系统效率

2)非阻塞IO:程序未接受到数据时程序一直执行,效率很低

3)异步IO:只能绑定一个文件描述符用来读取数据,但是效率很高

4)多路复用IO:

select:

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

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

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

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

poll:

        1.poll监听集合中的文件描述符没有上限

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

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

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

epoll:

3.函数接口:

1)select

 int select(int nfds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout);

功能:select建听描述符集合中是否有文件描述编程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;
}

2)poll

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 */
               short revents;     /* returned events */
           };
        fd:监听的文件描述符

        events:要监听的事件  POLLIN:是否可读  POLLOUT:是否可写

        revents:实际产生的事件

读端

#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;
}

3)epoll

int epoll_create(int size);

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

参数:size:事件个数

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

 epoll_ctl 

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;

epoll_wait 

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

功能:监听事件表的事件

参数:

epfd:文件描述符

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

maxevents:最多存放事件的个数

timeout:设定监听的时间(超过该时间则不再监听)

-1 一直监听直到有事件发生

返回值:

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

失败返回-1 

如果时间达到仍没有事件发生返回0 

读端

#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;
}

写端

#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/737358.shtml

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

相关文章

牛客网KY15 abc

题目 描述&#xff1a; 设a、b、c均是0到9之间的数字&#xff0c;abc、bcc是两个三位数&#xff0c;且有&#xff1a;abcbcc532。求满足条件的所有a、b、c的值。 输入描述&#xff1a; 题目没有任何输入。 输出描述&#xff1a; 请输出所有满足题目条件的a、b、c的值。 a、b、c…

2024年零基础自学网络安全/Web安全,看这一篇就够了

作为一个安全从业人员&#xff0c;我自知web安全的概念太过于宽泛&#xff0c;我本人了解的也并不够精深&#xff0c;还需要继续学习。 但又不想新入行的人走弯路&#xff0c;所以今天随手写写关于web安全的内容&#xff0c;希望对初次遇到web安全问题的同学提供帮助&#xff…

【Leetcode】top 100 子串

560 和为k的子数组 给你一个整数数组 nums 和一个整数 k &#xff0c;请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 思路&#xff1a;一次遍历元素&#xff0c;当当前累积和超过k时&#xff08;若当前元素>k&#xff0c;直接切换…

设计模式:软件开发的秘密武器

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

HTML:注释的 5 种场景和 5 点注意事项

你好&#xff0c;我是云桃桃。 HTML 代码注释是用来在 HTML 源代码中添加一些说明性文字&#xff0c;而不会显示在页面中的内容。它们不会在浏览器中显示或渲染。 现在我们一起来看看它的语法&#xff0c;用途和注意事项吧。 注释语法 HTML 注释的基本语法格式是: <!--…

利用Nginx正向代理实现局域网电脑访问外网

引言 在网络环境中&#xff0c;有时候我们需要让局域网内的电脑访问外网&#xff0c;但是由于网络策略或其他原因&#xff0c;直接访问外网是不可行的。这时候&#xff0c;可以借助 Nginx 来搭建一个正向代理服务器&#xff0c;实现局域网内电脑通过 Nginx 转发访问外网的需求…

绝赞春招拯救计划 -- 数据结构篇

哈希表 来吧&#xff01;一文彻底搞定哈希表&#xff01; - 知乎 (zhihu.com) 百科解释&#xff1a; “散列表&#xff08;Hash table&#xff0c;也叫哈希表&#xff09;&#xff0c;是根据键&#xff08;Key&#xff09;而直接访问在内存存储位置的数据结构。也就是说&…

免费的 AI 视频生成工具 Moonvalley 厉害了!Moonvalley 怎么用(保姆级教程)

一、Moonvalley 介绍 Moonvalley&#xff0c;号称地表最强的 AI 视频生成工具&#xff0c;到底有多厉害&#xff1f;今天一起来看一下~ 这是 Moonvalley 官网的介绍&#xff1a; Moonvalley 是一个开创性的新型文本到视频的生成式 AI 模型。用简单的文本即可创建出惊人的电影和…

【机器学习】支持向量机 | 支持向量机理论全梳理 对偶问题转换,核方法,软间隔与过拟合

支持向量机走的路和之前介绍的模型不同 之前介绍的模型更趋向于进行函数的拟合&#xff0c;而支持向量机属于直接分割得到我们最后要求的内容 1 支持向量机SVM基本原理 当我们要用一条线&#xff08;或平面、超平面&#xff09;将不同类别的点分开时&#xff0c;我们希望这条…

蓝桥杯练习系统(算法训练)ALGO-976 P0804字符串压缩

资源限制 内存限制&#xff1a;256.0MB C/C时间限制&#xff1a;1.0s Java时间限制&#xff1a;3.0s Python时间限制&#xff1a;5.0s 编写一个函数void strcompress(char *s)&#xff0c;输入一个字符串&#xff08;只包含小写字母和空格&#xff0c;且长度小于1000&am…

MotionCtrl: A Unified and Flexible Motion Controller for Video Generation

MotionCtrl: A Unified and Flexible Motion Controller for Video Generation 这篇论文是基于VideoCrafter的&#xff0c;而VideoCrafter是基于LVDM的 关于LVDM可以看https://blog.csdn.net/Are_you_ready/article/details/136615853 2023年12月6日发表在arxiv 这篇论文讨论…

【深度学习】线性回归

Linear Regression 一个例子线性回归机器学习中的表达评价函数好坏的度量&#xff1a;损失&#xff08;Loss&#xff09;损失函数&#xff08;Loss function&#xff09;哪个数据集的均方误差 (MSE) 高 如何找出最优b和w?寻找最优b和w如何降低损失 (Reducing Loss)梯度下降法梯…

我们都想要一个好的前景

大家好&#xff0c;我是记得诚。 有个读者向我咨询了一下他的就业问题。 问题&#xff1a; 大佬好&#xff0c;我咨询一下就业方向问题。我本身是大专毕业的&#xff0c;专业是应用电子技术&#xff0c;学了一部分硬件知识和软件。 毕业后第一份工作是去一家比较小的医疗机…

天猫魔盒解码报错

最近有个天猫魔盒&#xff08;Tmall,MagicBox_M17,MagicBox_M17&#xff09;有报错&#xff0c;报错信息如下&#xff1a; generic_decoder.cc, (line 98): Too many frames backed up in the decoder, dropping frame with timestamp 4219980314https://chromium.googlesourc…

工人安全绳穿戴识别系统---豌豆云

工人安全绳穿戴识别系统采用视频图像自动识别的形式&#xff0c;豌豆云工人安全绳穿戴识别系统通过安装在作业区域的监控摄像头。 一旦发现工人高空作业未佩戴安全带的情况&#xff0c;系统可以立即发出告警&#xff0c;相关人员可以迅速采取措施&#xff0c;防止事故的发生。…

记一次多线程写入文件出现IOException:Stream Closed的问题

背景 网关在解析1000个05文件&#xff08;txt&#xff09;写入到SFTP文件时&#xff0c;是每次读取1000 * 5条数据&#xff0c;然后每1000笔数据创建一个线程逐条数据进行字段数值映射转换&#xff0c;一共创建5个线程扔到线程池进行处理。每条数据解析完都会将数据写入到SFTP的…

绪论——算法设计原则【数据科学与工程算法基础】

一、题记 最近情绪不太稳定&#xff0c;些许烦躁&#xff0c;也就一直没践行前边说的“学习记录”的想法。现在开始做了&#xff0c;春华易逝&#xff0c;正当时&#xff0c;有想法就去做&#xff0c;踌躇懊悔是这个年纪最不该做的事。 二、前言 之前说了分块做这个系列&#x…

101. Go单测系列1---使用monkey打桩

本文将介绍如何在单元测试中使用monkey进行打桩。 monkey支持为任意函数及方法进行打桩。 monkey介绍 monkey是一个Go单元测试中十分常用的打桩工具&#xff0c;它在运行时通过汇编语言重写可执行文件&#xff0c;将目标函数或方法的实现跳转到桩实现&#xff0c;其原理类似…

我用 Python 做了个小仙女代码蹦迪视频

前言 最近在B站上看到一个漂亮的仙女姐姐跳舞视频&#xff0c;循环看了亿遍又亿遍&#xff0c;久久不能离开&#xff01; 看着仙紫小姐姐的蹦迪视频&#xff0c;除了一键三连还能做什么&#xff1f;突发奇想&#xff0c;能不能把小仙女的蹦迪视频转成代码舞呢&#xff1f; 说…

uniapp引入jQuery

安装 npm install jquery --saveoryarn add jquery引入 import Vue from vue import jquery from "jquery"; Vue.prototype.$ jquery;<template><view>abc</view> </template><script>export default {data() {return {}}} </scr…