打飞机时和ML时在计算长度时只有相同的什么相同吗

Nginx的事件驱动模型


当 Nginx 刚刚启动时茬等待事件部分,也就是打开了 80 或 443 端口这个时候在等待新的事件进来,比如新的客户端连上了 Nginx 向我们发起了连接此步往往对应 epoll 的 epoll wait 方法,这个时候的 Nginx 其实是处于 sleep 这样一个进程状态的当操作系统收到了一个建立 TCP 连接的握手报文时并且处理完握手流程以后,操作系统就会通知 epoll wait 这个阻塞方法告诉它可以往下走了,同时唤醒 Nginx worker 进程

接着往下走之后,会去找操作系统索要要事件操作系统会把他准备好的事件,放在事件队列中从这个事件队列中可以获取到需要处理的事件。比如建立连接或者收到一个 TCP 请求报文

取出以后就会进行循环处理事件,如上就是处理事件的一个循环:当发现队列中不为空就把事件取出来开始处理事件;在处理事件的过程中,可能又生成新的事件比洳说发现一个连接新建立了,可能要添加一个超时时间比如默认的 60 秒,也就是说 60 秒之内如果浏览器不向 Nginx 发送请求的话Nginx 就会把这个连接關掉;又比如说当 Nginx 发现已经收完了完整的 HTTP 请求以后,可以生成 HTTP 响应了那么这个生成响应是需要 Nginx 可以向操作系统的写缓存中心里面去把响應写进去,要求操作系统尽快的把这样一段响应内容发到浏览器上也就是说可能在处理过程中可能会产生新的事件,就是循环处理事件蔀分指向的事件队列部分等待下一次来处理。

如果所有的事件都处理完成以后呢又会返回到等待事件部分。

在学习了 Nginx 事件循环后我們再去理解有时候使用一些第三方模块,这些第三方模块可能会做大量的 CPU 运算这样的计算任务会导致处理一个事件的时间非常的长;在仩面的一个流程图中,可以看到会导致队列中的大量事件会长时间得不到处理从而引发恶性循环,所以 Nginx 不能容忍有些第三方模块长时间嘚消耗大量的 CPU 进行计算任务我们可以看到像 GZIP 这样的模块,他们都不会在一次使用大量的 CPU 而是分段使用这些都与 Nginx 的事件循环有关的。

上媔主要描述了 Nginx 是如何处理事件的以及 Nginx 事件循环的流程是怎么样的为下一步讲解 Nginx 事件循环流程中是如何从操作系统中获取等待处理的事件莋铺垫,并且通过事件循环了解到为什么 Nginx 不期望第三方模块中出现大量 CPU 的计算任务

Nginx事件循环带来的后果


  1. 第三方模块做大量的CPU计算,导致峩处理一个事件会特别长会导致后续队列中的大量事件长事件得不到处理
  2. 所以nginx无法容忍第三方模块长时间使用CPU执行计算任务
  3. 我们看到gzip模塊不是一次计算而是分段计算


有100万用户同时与一个进程保持着TCP连接,而每一时刻只有几十个或几百个TCP连接是活跃的(接收到TCP包)也就是說,在每一时刻进程只需要处理这100万连接中的一小部分连接。那么如何才能高效地处理这种场景呢?进程是否在每次询问操作系统收集有事件发生的TCP连接时把这100万个连接告诉操作系统,然后由操作系统找出其中有事件发生的几百个连接呢


select每次收集事件时,都把这100万連接的套接字传给操作系统(这首先就是用户态内存到内核态内存的大量复制)而由操作系统内核寻找这些连接上有没有未处理的事件,将会是巨大的资源浪费这里有个非常明显的问题,即在某一时刻进程收集有事件的连接时,其实这100万连接中的大部分都是没有事件發生的


它在Linux内核中申请了一个简易的文件系统,把原先的一个select或者poll调用分成了3个部分:

这样只需要在进程启动时建立1个epoll对象,并在需偠的时候向它添加或删除连接就可以了因此,在实际收集事件时epoll_wait的效率就会非常高,因为调用epoll_wait时并没有向它传递这100万个连接内核也鈈需要去遍历全部的连接。

epoll是基于回调函数的无轮询。如果当套接字比较多的时候每次select()都要通过遍历FD_SETSIZE个Socket来完成调度,不管哪个Socket是活跃嘚都遍历一遍。这会浪费很多CPU时间如果能给套接字注册某个回调函数,当他们活跃时自动完成相关操作,那就避免了轮询这正是epoll(Linux)、kqueue(FreeBSD)、/dev/poll(soloris)做的。举个经典例子假设你在大学读书,住的宿舍楼有很多间房间你的朋友要来找你。select版宿管大妈就会带着你的朋友挨个房间去找直到找到你为止。而epoll版宿管大妈会先记下每位同学的房间号你的朋友来时,只需告诉你的朋友你住在哪个房间即可不用亲自带着伱的朋友满大楼找人。如果来了10000个人都要找自己住这栋楼的同学时,select版和epoll版宿管大妈谁的效率更高,不言自明同理,在高并发服务器中轮询I/O是最耗时间的操作之一,select、epoll、/dev/poll的性能谁的性能更高同样十分明了。

关于epoll的实现原理本文不会具体介绍,这里只是介绍epoll的工莋流程epoll的使用是三个函数:

 
首先epoll_create函数会在内核中创建一块独立的内存存储一个eventpoll结构体,该结构体包括一颗红黑树和一个链表如下图所礻:

然后通过epoll_ctl函数,可以完成两件事
  • (1)将事件添加到红黑树中,这样可以防止重复添加事件;
  • (2)将事件与网卡建立回调关系当事件發生时,网卡驱动会回调ep_poll_callback函数将事件添加到epoll_create创建的链表中。
 
最后通过epoll_wait函数,检查并返回链表中是否有事件该函数是阻塞函数,阻塞時间为timeout当双向链表有事件或者超时的时候就会返回链表在计算长度时只有相同的什么(发生事件的数量)。
 

 
维护了一个epitem的数据结构他通过兩种数据结构把这两件事件分开实现,也就是Nginx每次取活跃连接的时候我们只需要去遍历一个链表,这个链表里仅仅只有活跃的的连接、這样我们速度效率就会很高
1、创建:Nginx收到80端口建立连接的请求请求连接成功以后,这时候我要添加一个读事件这个读事件是用来读取http消息的,这个时候我可能会添加一个新的事件、或者是写事件这个添加我只会放到红黑树中,二叉平衡树能保证我的插入效率是logn的复杂喥
2、添加:当操作系统接收到网卡中发送来一个报文的时候这个链表就会增加一个链接
3、修改:读取一个事件的时候链表自然就没了
4、刪除:如果我我不想再处理读事件和写事件,我只要从这个平衡二叉树移除一个节点
5、获取句柄:就是遍历活跃链接的链表从内核态读取到用户态
}

该楼层疑似违规已被系统折叠 

每忝努力学习重建大脑
培养出新的好习惯来取代恶习
去寻找更高尚、更长久的幸福和快乐
来取代看AV和SY得到的短暂的快感
你就不再需要色情這种虚拟、有害的垃圾了!
多吃素,不吃垃圾食品排毒养颜,把脸上的痘痘都去掉
去锻炼身体炼成六块腹肌,打造完美的身材
去读书培养自己的文艺气质
努力赚钱,去旅行买喜欢的东西
去多交朋友,感受友情的温暖
去谈恋爱感受真正的美好爱情,远离粗制滥造色凊电影中对爱情的扭曲
珍惜自己、爱护自己、对自己负责
即使有一天很难受也要相信
美好的事情很快就会发生


}

如果你试过其他博文的方法都不荇的话你看看你wxml绑定的办法中是否有用到类似的传参方式:

我是通过uni-app编译成的小程序,写法如下

其中list是数据列表index是遍历listindex,这种传参方式就会导致setData 传输过大告警解决方法是使用data-的形式传参


    

特意试了很多其他写法,比如不传index只传单独的list、将变量index换成其他变量、不使用JSON.stringify()等操作都不会出现警告

}

我要回帖

更多关于 在计算长度时只有相同的什么 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信