首页 > 其他分享 >Event poll 在项目中的应用

Event poll 在项目中的应用

时间:2025-01-17 11:22:18浏览次数:1  
标签:请求 读写 客户端 线程 应用 fd poll Event wait

水平触发:

Level_triggered(水平触发):当被监控的文件描述符(fd)上有可读写事件发生时,epoll_wait()会通知处理程序去读写。如果这次没有把数据一次性全部读写完(如读写缓冲区太小),那么下次调用 epoll_wait()时,它还会通知你在上没读写完的文件描述符上继续读写,当然如果你一直不去读写,它会一直通知你!!!如果系统中有大量你不需要读写的就绪文件描述符,而它们每次都会返回,这样会大大降低处理程序检索自己关心的就绪文件描述符的效率!

边缘触发:

Edge_triggered(边缘触发):当被监控的文件描述符上有可读写事件发生时,epoll_wait()会通知处理程序去读写。如果这次没有把数据全部读写完(如读写缓冲区太小),那么下次调用epoll_wait()时,它不会通知你,也就是它只会通知你一次,直到该文件描述符上出现第二次可读写事件才会通知你!!!这种模式比水平触发效率高,系统不会充斥大量你不关心的就绪文件描述符!!!

来源:https://zhuanlan.zhihu.com/p/532789377

场景:

基于gsoap服务;处理短暂的HTTP请求;但是请求非常频繁;需要多线程处理设备发现请求和HTTP接口请求

写法1:

gsoap 服务主要做设备发现的响应和onvif服务的响应;启动任务,启动两条常驻线程(或者线程池启两条线程,在线程任务task里while循环检测是否有socket链接),时刻检测两个fd(设备发现的socket 发的,和http请求的tcp socket fd)上是否有链接请求;soap_server;

1的问题:

使用普通线程常驻:设备发现(加入多播组的UDP socket)也好,onvif的接口请求(HTTP请求,tcp连接)都是短连接,如果客户端多,并且请求频繁的话,线程的真实使用率较高,但是如果只是偶尔几个客户端请求,常驻线程大部分时间都没做事;

使用线程池+while循环:这样做虽然是在使用线程池处理短连接任务,但是为了避免错过任何客户端请求,while循环必须一直运行,也就变相的将线程池中处理短任务的线程,变成长期占用;现成池中的线程长期不能停歇;

基于此,如果服务是多端口的,即进行HTTP响应的端口不止430;(常用的onvif服务都是单端口,但是也可以一个IP加入多播组,多个端口接收设备发现信息,并各自响应onvif请求,客户端发送onvif协议交互,可选择端口)

上边1的开发逻辑,要么常驻N条线程,要么出现线程池中多条线程,并且由于有些线程池是notify_one 的,当一下启动多条线程池任务时候,很可能导致有些任务永远不会被执行(因为线程池中的线程一直被while循环占用,线程池中的task是长任务)

 

综上:要么占用非常多的线程,要么就导致任务无法被处理;基于此,既要解放线程池,又不能错误任何客户端过来的请求;

写法2:EVENT pool (水平触发)+线程池

单独的线程(开一个普通线程处理 event pool 的wait)处理event pool 的wait事件;当接收到 读写事件的时候存入线程池中的task队列;注意区分读写事件;并不是所有类型事件都需要监听,客户端过来的链接只需要监听读事件即可;

event pool 开水平触发模式;

问题:

当启动多个端口,并且有多个客户端过来链接本服务时候,由于wait到的fd的处理事件,是放到任务队列中等待线程池消耗的;就导致任务不是第一时间处理了;没有第一时间wait到就读socket缓冲,根据(“如果这次没有把数据一次性全部读写完(如读写缓冲区太小),那么下次调用 epoll_wait()时,它还会通知你在上没读写完的文件描述符上继续读”)就会出现一个wait到的fd的事件一直重复;除非能立即消耗掉fd的这个读写事件,否则会频繁被event_pool wait到,导致线程池的任务队列也会爆慢,任务都是重复的;

这就说明水平触发模式获取到的任务,你需要立即执行;

写法3: EVENT pool (边缘触发)+线程池

单独的线程处理event pool 的wait事件((开一个普通线程处理 event pool 的wait));当接收到 读写事件的时候存入线程池中的task队列;注意区分读写事件;并不是所有类型事件都需要监听,客户端过来的链接只需要监听读事件即可;

//#if defined(_WIN32)
//        unsigned long ul = 1;
//        int ret1 = ioctlsocket(sockfd, FIONBIO, &ul); //#else
//        int ul = 1;
//        int ret1 = ioctl(sockfd, FIONBIO, &ul); 
//#endif //defined(_WIN32)//ev.events = EPOLLIN| EPOLLET;
        ///ev.events = EPOLLIN;//默认水平触发
      

问题:

当有多个客户端都在访问一个gsoap 的onvif服务的时候;只会通知一次,wait到一次;虽然可以免去重复任务被wait到,但是可能当前fd有多个读写事件,每个事件来自不同的客户端,所以这里如果你无法把本次wait到的FD,的内核中的读写事件全部处理完,就会造成有些事件未能及时处理,就会造成,客户端的请求无法及时回复,甚至是下次发请求,回复上一次的请求响应;如图,需要一次性将客户端1,2,5对fd21的请求处理完;也就是socket读尽;一次解析多条请求,分别放入任务队列;

 写法4:水平触发+阻塞任务处理+线程池

使用水平触发,为了避免任务重复,必须等到线程队列中将当前fd的这个当前任务处理完,在wait(接收)本fd的事件;

如:wait到fd =1;的来自客户端1的请求,放入任务队列,记录fd1有待处理任务,等线程池执行完fd=1的任务,标记处理完成;在fd=1;被标记为处理完前wait到的fd=1的事件,全部丢弃;直到处理完fd=1来自客户端1的任务;以此类推,避免重复,又能将多个客户端的任务处理完

标签:请求,读写,客户端,线程,应用,fd,poll,Event,wait
From: https://www.cnblogs.com/8335IT/p/18676581

相关文章

  • Qt以共享内存方式限制应用多开
    1.创建共享内存,如果键所标识的共享内存段已经存在,则不执行附加操作,并返回false。#include<QApplication>#include<QSharedMemory>#include<QMessageBox>intmain(intargc,char*argv[]){QApplicationa(argc,argv);//"AK"键staticQSharedMemory......
  • 创建一个.NET MAUI应用(二)
    开发本机跨平台.NET多平台应用UI(.NETMAUI)应用需要VisualStudio202217.12或更高版本 安装若要创建.NETMAUI应用,需要下载最新版本的VisualStudio2022:下载VisualStudio2022社区版下载VisualStudio2022专业版下载VisualStudio2022企业......
  • 《研发管理 APQP 软件系统》——汽车电子行业的应用收益分析
    全星研发管理APQP软件系统在汽车电子行业的应用收益分析在汽车电子行业,技术革新迅猛,市场竞争激烈。《全星研发管理APQP软件系统》的应用,为企业带来了革命性的变化,诸多收益使其成为行业发展的关键驱动力。《全星研发管理APQP软件系统》极大地优化了研发流程。在项目......
  • 2 应用层
    2应用层2.1网络应用原理网络应用:能够运行在不同的端系统和通过网络彼此通信的程序。注:在端系统上运行,而不是在网络核心上运行。网络应用是计算机网络存在的理由。2.1.1应用体系结构(applicationarchitecture)客户-服务器体系结构(client-serverarchitecture)server:响应......
  • 深入对比:PyTorch与TensorFlow的异同及应用场景分析
    引言在人工智能(AI)领域,尤其是深度学习中,PyTorch与TensorFlow是两大最流行的框架。它们都为研究人员和工程师提供了构建神经网络模型的强大工具,但二者的设计理念、使用方法以及适用场景却存在显著差异。了解这些差异能够帮助开发者根据具体需求选择合适的框架。本文将从多个角......
  • Gemini 多模态功能:七大应用场景,解锁 AI 无限可能
    你是否想象过,一台机器可以像人类一样,同时理解图像、视频和文字? GoogleGemini的诞生,让这一想象成为现实。作为GoogleAI的最新成果,Gemini的多模态能力为企业带来了前所未有的机遇。本文将以性能卓越的Gemini1.5Pro为例,分享Gemini在七大实际应用场景中的表现,并重点关注......
  • 计算机毕业设计Springboot运动健康APP 基于Spring Boot框架的健身与健康管理移动应用
    计算机毕业设计Springboot运动健康APPu8mr9vrk(配套有源码程序mysql数据库论文)本套源码可以先看具体功能演示视频领取,文末有联xi可分享随着科技的飞速发展和人们对健康生活方式的追求,运动健康APP应运而生,成为现代生活中不可或缺的健康管理工具。这类APP不仅能够帮助用户记......
  • 专为高性能计算和低功耗应用设计的MPF100T-1FCVG484E MPF100TL-FCSG325E MPF100TL-FCV
    ‌PolarFireFPGA是Microchip推出的一款高性能、低功耗的FPGA产品系列,特别适用于各种需要高性能计算和低功耗的应用场景‌。这些器件包括MPF100T-1FCVG484EMPF100TL-FCG484EMPF100TL-FCG484IMPF100TL-FCSG325EMPF100TL-FCVG484EMPF100TL-FCVG484IFPGA-现场可编程门阵列......
  • SpringBoot源码解析(七):应用上下文结构体系
    SpringBoot源码系列文章SpringBoot源码解析(一):SpringApplication构造方法SpringBoot源码解析(二):引导上下文DefaultBootstrapContextSpringBoot源码解析(三):启动开始阶段SpringBoot源码解析(四):解析应用参数argsSpringBoot源码解析(五):准备应用环境SpringBoot源码解......
  • 【IO复用】select、poll、epoll的区别
    目录啥是IO复用selectpollepoll为啥select和poll需要遍历selectpollepoll为什么用select和poll时·内核·需要去轮询历史原因调度机制epoll如何知道是哪个文件描述符有变化?总结啥是IO复用在传统阻塞IO模式下,每个线程会阻塞等待一个fd(文件描述符或套接......