当前位置: 首页 > news >正文

做彩铃的网站视频seo优化教程

做彩铃的网站,视频seo优化教程,湖南至诚建设机械有限公司网站,潍坊seo排名高级IO——五种IO模型 首先我们之前在基础IO部分就学过IO的过程分等待过程和读写过程! 比如我们的scanf除了从键盘缓冲区读取数据所花的时间,主要的时间花费放在了等你输入的过程! 所以我们如果想提高我们的IO效率,我们除了要缩…

高级IO——五种IO模型

首先我们之前在基础IO部分就学过IO的过程分等待过程和读写过程!

比如我们的scanf除了从键盘缓冲区读取数据所花的时间,主要的时间花费放在了等你输入的过程!

所以我们如果想提高我们的IO效率,我们除了要缩减读取数据,主要的是减少花费在等你输入的时间!可是我们肯定不可能决定用户的输入速度,所以我们就只能让这个等待时间我们的程序去做其他事情,这样就可以减少等待IO花费的时间了!

由此我们就可以引出我们的5种IO模型了!(我们用钓鱼做例子)

阻塞IO: 在内核将数据准备好之前, 系统调用会一直等待. 所有的套接字, 默认都是阻塞方式
老老实实抓着一根杆子钓鱼,鱼来了就拉钩,否则就一直等!
非阻塞IO: 如果内核还未将数据准备好, 系统调用仍然会直接返回, 并且返回EWOULDBLOCK错误码.
把杆放在池塘里面就走了,过一段时间回来一次看一看,有鱼就掉,没鱼就离开去干其他事情。
信号驱动IO: 内核将数据准备好的时候, 使用SIGIO信号通知应用程序进行IO操作
放个信号器,来鱼了信号器报警,听到信号以后就去拉杆!
IO多路转接: 实际上最核心在于IO多路转接能够同时等待多个文件 描述符的就绪状态.
一次性放很多鱼竿,然后不停的检测所有鱼竿的情况,那个鱼竿有鱼就去处理那一根鱼竿!
 
异步IO: 由内核在数据拷贝完成时, 通知应用程序(而信号驱动是告诉应用程序何时可以开始拷贝数据).
直接让别人去钓鱼,等别人调完鱼,直接去取鱼!
前面四种IO我们称之为同步IO,我们先不看异步IO,那种钓鱼的效率最高?
当然是IO多路转接?为什么?因为杆多!!!鱼竿多自然钓鱼就多,因为不同鱼竿的等待时间重叠了!!!本身就是提高效率!
可是我们一般选择多是多路复用,而不是异步IO。为什么呢?因为首先异步IO看起来是让别人钓鱼,但是在程序中我们就要创建线程或子进程去做事,本身就要耗费较大资源,而且一旦设计多线程,就可能会出现很多问题,大幅度提高程序的复杂性!所以我们一般更青睐于多路转接的方法!
接下来我们来学习系统专门为多路复用设计的接口!
首先我们来介绍select
在此之前由于我们的fd都默认是阻塞式IO,所以我们先要将想要的fd设置为非阻塞式IO。
这个时候我们就要先用fcntl去设置相应的fd呢!
复制一个现有的描述符( cmd=F_DUPFD .
获得 / 设置文件描述符标记 (cmd=F_GETFD F_SETFD).
获得 / 设置文件状态标记 (cmd=F_GETFL F_SETFL).
获得 / 设置异步 I/O 所有权 (cmd=F_GETOWN F_SETOWN).
获得 / 设置记录锁 (cmd=F_GETLK,F_SETLK F_SETLKW).
比如下面的程序就是先获取一个程序的旧的标志位,然后我们再设置其为非阻塞!
接下来我们就可以学习select呢
返回值:n>0的时候就代表有多少个fd已经就绪,n==0就是没有就绪但是倒计时已经到了,n<0就是出错了!
timeval是一个结构体,如下图,分别是秒和微秒!
并且timeval还是个输入输出形参数!
也即比如我们设置的是5,0也即5秒返回一次,如果过了两秒就有就绪了,那么timeval这个时候就会使3,0.
然后我们再来了解最重要的是fd_set是什么?
其实就是一张位图,readfds里面响应的位置如果被设置为1,则关心相应事件的读,writefds则关心写!
当传入的时候我们就是告诉内核那个fd我们要关心,返回的时候,传出的就是那个fd已经可以读取了!不会产生等待了!
我们在这里先讲一下select的一些限制,既然fd_set是结构体,那么其中等待的fd有没有上限呢?是多少呢?
不同的系统可能跑出来的是不一样的,但是大差不差!
并且我们每一次都要重新给select传表,我们还要用一个辅助数组提前记录哪些fd我们要监听,也是一个开销!
所以我们可以总结一下select的优缺点
优点:主要是已经实现了多路转接了!
缺点:
1.fd有上限!
2.输入输出型参数多,需要不停的数据拷贝和遍历修改,会导致效率低下!
3.而且还要辅助数组记录我们要关心的fd
下面是一个基于select的多路转接的单词翻译器的实现!
然后我们在学习epoll之前,先看一下poll!
第一个参数就是一个struct pollfd的数组
第二个参数就是数组中元素的个数
第三个参数与select一致
至于struct pollfd的结构主要包含关心的fd,还有两个短整形变量!
如果想要添加指令就只用将短整数&上对应的宏就可以了!!!
其中events是传入给poll的,revents是poll要写入的,我们进行读取就可以!
poll相对于select首先克服了数量有限的问题,并且减少了遍历,并且不用我们维护辅助数组了!
也更容易编写!!!
但是我们仍然需要去不停遍历整个数组,那么当数量增多以后,主要矛盾就从等待变成了遍历了!
如果学会了select,那poll难度应该不大,就不再过多赘述!而epoll则在此基础之上又大幅度提高效率,所以下面我们来学习epoll!!!
epoll 的事件注册函数 .
它不同于 select() 是在监听事件时告诉内核要监听什么类型的事件 , 而是在这里先注册要监听的事件类型 .
第一个参数是 epoll_create() 的返回值 (epoll 的句柄 ).
第二个参数表示动作,用三个宏来表示 .
第三个参数是需要监听的 fd.
第四个参数是告诉内核需要监听什么事 .
第二个参数的取值 :
EPOLL_CTL_ADD :注册新的 fd epfd 中;
EPOLL_CTL_MOD :修改已经注册的 fd 的监听事件;
EPOLL_CTL_DEL :从 epfd 中删除一个 fd
struct epoll_event 结构如下
events 可以是以下几个宏的集合:
EPOLLIN : 表示对应的文件描述符可以读 ( 包括对端 SOCKET 正常关闭 );
EPOLLOUT : 表示对应的文件描述符可以写 ;
EPOLLPRI : 表示对应的文件描述符有紧急的数据可读 ( 这里应该表示有带外数据到来 );
EPOLLERR : 表示对应的文件描述符发生错误 ;
EPOLLHUP : 表示对应的文件描述符被挂断 ;
EPOLLET : EPOLL 设为边缘触发 (Edge Triggered) 模式 , 这是相对于水平触发 (Level Triggered) 来说的 . EPOLLONESHOT:只监听一次事件 , 当监听完这次事件之后 , 如果还需要继续监听这个 socket 的话 , 需要 再次把这个socket 加入到 EPOLL 队列里
收集在 epoll 监控的事件中已经发送的事件 .
参数 events 是分配好的 epoll_event 结构体数组 .
epoll 将会把发生的事件赋值到 events 数组中 (events 不可以是空指针,内核只负责把数据复制到这个 events数组中,不会去帮助我们在用户态中分配内存 ).
maxevents 告之内核这个 events 有多大,这个 maxevents 的值不能大于创建 epoll_create() 时的 size.
参数 timeout 是超时时间 ( 毫秒, 0 会立即返回, -1 是永久阻塞 ).
如果函数调用成功,返回对应 I/O 上已准备好的文件描述符数目,如返回 0 表示已超时 , 返回小于 0 表示函 数失败
学了epoll的基本使用以后,我们来学习一下epoll的原理!
当某一进程调用 epoll_create 方法时, Linux 内核会创建一个 eventpoll 结构体,这个结构体中有两个成 员与epoll 的使用方式密切相关 .
主要是一个红黑树和一个双链表的队列!
每个被检测的fd都会被放入红黑树,一旦事件就绪,就会调用回调函数,让操作系统从红黑树中找到相关的rbn成员然后读取其信息,然后在等待队列中添加,这样就我们进行读取事件的时候就是在等待队列中读取事件了,并且在这个过程中事件主动回调,时间复杂度为o(1),比我们之前的select和poll效率拥有了质的提升!!!
总结一下 , epoll 的使用过程就是三部曲 :
调用 epoll_create 创建一个 epoll 句柄 ;
调用 epoll_ctl, 将要监控的文件描述符进行注册 ;
调用 epoll_wait, 等待文件描述符就绪 ;
epoll 的优点 ( select 的缺点对应 )
接口使用方便 : 虽然拆分成了三个函数 , 但是反而使用起来更方便高效 . 不需要每次循环都设置关注的文 件描述符, 也做到了输入输出参数分离开
数据拷贝轻量 : 只在合适的时候调用 EPOLL_CTL_ADD 将文件描述符结构拷贝到内核中 , 这个操作并不频 繁( select/poll 都是每次循环都要进行拷贝 )
事件回调机制 : 避免使用遍历 , 而是使用回调函数的方式 , 将就绪的文件描述符结构加入到就绪队列中 , epoll_wait 返回直接访问就绪队列就知道哪些文件描述符就绪 . 这个操作时间复杂度 O(1). 即使文件描述 符数目很多, 效率也不会受到影响 . 没有数量限制: 文件描述符数目无上限
我们再来讲一下epoll的工作模式!
epoll2种工作方式-水平触发(LT)和边缘触发(ET)
假如有这样一个例子 :
我们已经把一个 tcp socket 添加到 epoll 描述符
这个时候 socket 的另一端被写入了 2KB 的数据
调用 epoll_wait ,并且它会返回 . 说明它已经准备好读取操作
然后调用 read, 只读取了 1KB 的数据
继续调用 epoll_wait......
水平触发 Level Triggered 工作模式
epoll 默认状态下就是 LT 工作模式 .
epoll 检测到 socket 上事件就绪的时候 , 可以不立刻进行处理 . 或者只处理一部分 .
如上面的例子 , 由于只读了 1K 数据 , 缓冲区中还剩 1K 数据 , 在第二次调用 epoll_wait , epoll_wait
仍然会立刻返回并通知 socket 读事件就绪 .
直到缓冲区上所有的数据都被处理完 , epoll_wait 才不会立刻返回 .
支持阻塞读写和非阻塞读写
边缘触发 Edge Triggered 工作模式
如果我们在第 1 步将 socket 添加到 epoll 描述符的时候使用了 EPOLLET 标志 , epoll 进入 ET 工作模式 .
epoll 检测到 socket 上事件就绪时 , 必须立刻处理 .
如上面的例子 , 虽然只读了 1K 的数据 , 缓冲区还剩 1K 的数据 , 在第二次调用 epoll_wait 的时候 ,
epoll_wait 不会再返回了 .
也就是说 , ET 模式下 , 文件描述符上的事件就绪后 , 只有一次处理机会 .
ET 的性能比 LT 性能更高 ( epoll_wait 返回的次数少了很多 ). Nginx 默认采用 ET 模式使用 epoll.
只支持非阻塞的读写
select poll 其实也是工作在 LT 模式下 . epoll 既可以支持 LT, 也可以支持 ET.
对比 LT ET
LT epoll 的默认行为 . 使用 ET 能够减少 epoll 触发的次数 . 但是代价就是强逼着程序猿一次响应就绪过程中就把 所有的数据都处理完.
相当于一个文件描述符就绪之后 , 不会反复被提示就绪 , 看起来就比 LT 更高效一些 . 但是在 LT 情况下如果也能做到
每次就绪的文件描述符都立刻处理, 不让这个就绪被重复提示的话 , 其实性能也是一样的 .
另一方面 , ET 的代码复杂程度更高了 .
理解 ET 模式和非阻塞文件描述符
使用 ET 模式的 epoll, 需要将文件描述设置为非阻塞 . 这个不是接口上的要求 , 而是 " 工程实践 " 上的要求 .
假设这样的场景 : 服务器接受到一个 10k 的请求 , 会向客户端返回一个应答数据 . 如果客户端收不到应答 , 不会发送第 二个10k 请求 .
如果服务端写的代码是阻塞式的read, 并且一次只 read 1k 数据的话 (read 不能保证一次就把所有的数据都读出来 , 参考 man 手册的说明 , 可能被信号打断 ), 剩下的 9k 数据就会待在缓冲区中
此时由于 epoll ET 模式 , 并不会认为文件描述符读就绪 . epoll_wait 就不会再次返回 . 剩下的 9k 数据会一直在缓 冲区中. 直到下一次客户端再给服务器写数据 . epoll_wait 才能返回 但是问题来了.
服务器只读到 1k 个数据 , 10k 读完才会给客户端返回响应数据 .
客户端要读到服务器的响应 , 才会发送下一个请求 客户端发送了下一个请求, epoll_wait 才会返回 , 才能去读缓冲区中剩余的数据
所以 , 为了解决上述问题 ( 阻塞 read 不一定能一下把完整的请求读完 ), 于是就可以使用非阻塞轮训的方式来读缓冲区 , 保证一定能把完整的请求都读出来.
而如果是 LT 没这个问题 . 只要缓冲区中的数据没读完 , 就能够让 epoll_wait 返回文件描述符读就绪 .
也即如果设置为非阻塞的时候,我们反复读取,一旦读完就会出错返回,如果阻塞模式,我们就会阻塞在读的地方,这显然是我们不能接受的,所以我们要把读设为非阻塞模式!!!
epoll 的使用场景
epoll 的高性能 , 是有一定的特定场景的 . 如果场景选择的不适宜 , epoll 的性能可能适得其反 .
对于多连接 , 且多连接中只有一部分连接比较活跃时 , 比较适合使用 epoll.
例如 , 典型的一个需要处理上万个客户端的服务器 , 例如各种互联网 APP 的入口服务器 , 这样的服务器就很适合 epoll.
如果只是系统内部 , 服务器和服务器之间进行通信 , 只有少数的几个连接 , 这种情况下用 epoll 就并不合适 . 具体要根 据需求和场景特点来决定使用哪种IO模型

1.epoll惊群效应产生的原因
在Linux下使用epoll编写过socket的服务端程序,在多线程环境下可能会遇到epoll的惊群效应。那么什么是惊群效应呢。其产生的原因是什么呢?
在多线程或者多进程环境下,有些人为了提高程序的稳定性,往往会让多个线程或者多个进程同时在epoll_wait监听的socket描述符。当一个新的链接请求进来时,操作系统不知道选派那个线程或者进程处理此事件,则干脆将其中几个线程或者进程给唤醒,而实际上只有其中一个进程或者线程能够成功处理accept事件,其他线程都将失败,且errno错误码为EAGAIN。这种现象称为惊群效应,结果是肯定的,惊群效应肯定会带来资源的消耗和性能的影响。
那么如何解决这个问题。

2.惊群问题的解决方法
多线程环境下解决惊群解决方法
这种情况,不建议让多个线程同时在epoll_wait监听的socket,而是让其中一个线程epoll_wait监听的socket,当有新的链接请求进来之后,由epoll_wait的线程调用accept,建立新的连接,然后交给其他工作线程处理后续的数据读写请求,这样就可以避免了由于多线程环境下的epoll_wait惊群效应问题。

最后再把基于epoll的多路转接翻译服务器的代码贴在这里,这篇文章就到底为止了!

感谢观看!


文章转载自:
http://ferrugineous.rjbb.cn
http://prevaricator.rjbb.cn
http://skete.rjbb.cn
http://skylon.rjbb.cn
http://abraser.rjbb.cn
http://picturize.rjbb.cn
http://marconigram.rjbb.cn
http://detraction.rjbb.cn
http://unfading.rjbb.cn
http://endorsor.rjbb.cn
http://slip.rjbb.cn
http://actuality.rjbb.cn
http://inquisitor.rjbb.cn
http://javastation.rjbb.cn
http://microwave.rjbb.cn
http://rivadavia.rjbb.cn
http://wheelwright.rjbb.cn
http://sarcoidosis.rjbb.cn
http://nonwhite.rjbb.cn
http://concelebrant.rjbb.cn
http://serve.rjbb.cn
http://jazz.rjbb.cn
http://unauthorized.rjbb.cn
http://unleisured.rjbb.cn
http://teasy.rjbb.cn
http://labanotation.rjbb.cn
http://aerodonetics.rjbb.cn
http://sabaism.rjbb.cn
http://incapable.rjbb.cn
http://whereupon.rjbb.cn
http://rct.rjbb.cn
http://liassic.rjbb.cn
http://regulatory.rjbb.cn
http://kenaf.rjbb.cn
http://ferriage.rjbb.cn
http://flyway.rjbb.cn
http://fashioner.rjbb.cn
http://nippon.rjbb.cn
http://authorware.rjbb.cn
http://accessary.rjbb.cn
http://caravansary.rjbb.cn
http://singularly.rjbb.cn
http://truer.rjbb.cn
http://themis.rjbb.cn
http://masterwork.rjbb.cn
http://ostensory.rjbb.cn
http://acrid.rjbb.cn
http://tuesday.rjbb.cn
http://cranky.rjbb.cn
http://irinite.rjbb.cn
http://lalophobia.rjbb.cn
http://theretofore.rjbb.cn
http://dreadful.rjbb.cn
http://hedonic.rjbb.cn
http://neostyle.rjbb.cn
http://quichua.rjbb.cn
http://rollered.rjbb.cn
http://nuthatch.rjbb.cn
http://faintness.rjbb.cn
http://plunder.rjbb.cn
http://tatting.rjbb.cn
http://pouched.rjbb.cn
http://memorise.rjbb.cn
http://unliterate.rjbb.cn
http://raguly.rjbb.cn
http://tounament.rjbb.cn
http://fossilization.rjbb.cn
http://whatnot.rjbb.cn
http://glucoreceptor.rjbb.cn
http://predecessor.rjbb.cn
http://parthenogenetic.rjbb.cn
http://counterdrug.rjbb.cn
http://ebullioscopic.rjbb.cn
http://barnstorming.rjbb.cn
http://spectacled.rjbb.cn
http://galyak.rjbb.cn
http://crablike.rjbb.cn
http://endocarp.rjbb.cn
http://airburst.rjbb.cn
http://chromogram.rjbb.cn
http://notchy.rjbb.cn
http://penates.rjbb.cn
http://rootlet.rjbb.cn
http://enserf.rjbb.cn
http://lye.rjbb.cn
http://bivariate.rjbb.cn
http://surf.rjbb.cn
http://arenation.rjbb.cn
http://laguna.rjbb.cn
http://astrachan.rjbb.cn
http://human.rjbb.cn
http://appendiceal.rjbb.cn
http://montgolfier.rjbb.cn
http://wreath.rjbb.cn
http://microseism.rjbb.cn
http://hemoflagellate.rjbb.cn
http://untrodden.rjbb.cn
http://rumford.rjbb.cn
http://surfperch.rjbb.cn
http://buchmanism.rjbb.cn
http://www.dt0577.cn/news/68024.html

相关文章:

  • wordpress网站弹窗插件数据分析师就业前景
  • 外贸网站优化软件南召seo快速排名价格
  • 黄浦做网站武汉网站推广公司排名
  • 中牟网站制作百度平台推广联系方式
  • 如何查网站域名备案深圳百度国际大厦
  • 关于网站建设的问卷调查广州今日新闻最新消息
  • 昆山规模的网站建设公司有哪些推广普通话的宣传标语
  • 成人高考和自考的区别外贸seo优化公司
  • 制作网站怎么做导航栏seo搜索排名
  • 注册集团公司需要什么条件?百度首页排名优化多少钱
  • 装修公司网站源码php大一网页设计作业成品
  • 那个网站可以帮助做数学题营销软文范例大全100字
  • 有哪些可以做威客的网站如何做品牌宣传与推广
  • 朝阳区建设委员会网站青岛seo关键词排名
  • 网站建设兼职在哪找app拉新怎么对接渠道
  • 中国做b2b外贸的网站有哪些深圳百度关键
  • 精通网站建设 百度云百度指数专业版app
  • 成都科技网站建设联系电话网建
  • 广州小程序开发的公司排名百度首页优化排名
  • wordpress按照证书自媒体seo是什么意思
  • 局域网搭建工具佛山百度关键词seo外包
  • 小众写作网站2024年最新时政热点
  • 公司的网站怎么做推广方案软文推广发稿平台
  • 网站建设及发布的流程天津seo网站排名优化公司
  • 吉安网站建设兼职免费b2b网站推广
  • 曲阜公司网站建设价格便宜山东seo费用多少
  • wordpress安装完成网站seo教材
  • 做国内网站花费怎么弄属于自己的网站
  • 闵行网站制作公司北京seo关键词
  • asp.net做网站实例抖音指数查询