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

公司网站建设费入账嘉兴港区规划建设门户网站

公司网站建设费入账,嘉兴港区规划建设门户网站,网站开发哪里可做私活,公司网站做推广支出分录select/poll select 实现多路复用的方式是#xff0c;将已连接的 Socket 都放到一个文件描述符集合#xff0c;然后调用 select 函数将文件描述符集合拷贝到内核里#xff0c;让内核来检查是否有网络事件产生#xff0c;检查的方式很粗暴#xff0c;就是通过遍历文件描述…select/poll select 实现多路复用的方式是将已连接的 Socket 都放到一个文件描述符集合然后调用 select 函数将文件描述符集合拷贝到内核里让内核来检查是否有网络事件产生检查的方式很粗暴就是通过遍历文件描述符集合的方式当检查到有事件产生后将此 Socket 标记为可读或可写 接着再把整个文件描述符集合拷贝回用户态里然后用户态还需要再通过遍历的方法找到可读或可写的 Socket然后再对其处理。 所以对于 select 这种方式需要进行 2 次「遍历」文件描述符集合一次是在内核态里一个次是在用户态里 而且还会发生 2 次「拷贝」文件描述符集合先从用户空间传入内核空间由内核修改后再传出到用户空间中。 select 使用固定长度的 BitsMap表示文件描述符集合而且所支持的文件描述符的个数是有限制的在 Linux 系统中由内核中的 FD_SETSIZE 限制 默认最大值为 1024只能监听 0~1023 的文件描述符。 poll 不再用 BitsMap 来存储所关注的文件描述符取而代之用动态数组以链表形式来组织突破了 select 的文件描述符个数限制当然还会受到系统文件描述符限制。 但是 poll 和 select 并没有太大的本质区别都是使用「线性结构」存储进程关注的 Socket 集合因此都需要遍历文件描述符集合来找到可读或可写的 Socket时间复杂度为 O(n)而且也需要在用户态与内核态之间拷贝文件描述符集合这种方式随着并发数上来性能的损耗会呈指数级增长。 epoll epoll 的用法。如下的代码中先用e poll_create 创建一个 epol l对象 epfd再通过 epoll_ctl 将需要监视的 socket 添加到epfd中最后调用 epoll_wait 等待数据。 int s socket(AF_INET, SOCK_STREAM, 0); bind(s, ...); listen(s, ...)int epfd epoll_create(...); epoll_ctl(epfd, ...); //将所有需要监听的socket添加到epfd中while(1) {int n epoll_wait(...);for(接收到数据的socket){//处理} }epoll 通过两个方面很好解决了 select/poll 的问题。 第一点epoll 在内核里使用红黑树来跟踪进程所有待检测的文件描述字把需要监控的 socket 通过 epoll_ctl() 函数加入内核中的红黑树里红黑树是个高效的数据结构增删改一般时间复杂度是 O(logn)。而 select/poll 内核里没有类似 epoll 红黑树这种保存所有待检测的 socket 的数据结构所以 select/poll 每次操作时都传入整个 socket 集合给内核而 epoll 因为在内核维护了红黑树可以保存所有待检测的 socket 所以只需要传入一个待检测的 socket减少了内核和用户空间大量的数据拷贝和内存分配。 第二点 epoll 使用事件驱动的机制内核里维护了一个链表来记录就绪事件当某个 socket 有事件发生时通过回调函数内核会将其加入到这个就绪事件列表中当用户调用 epoll_wait() 函数时只会返回有事件发生的文件描述符的个数不需要像 select/poll 那样轮询扫描整个 socket 集合大大提高了检测的效率。 从下图你可以看到 epoll 相关的接口作用 poll 的方式即使监听的 Socket 数量越多的时候效率不会大幅度降低能够同时监听的 Socket 的数目也非常的多了上限就为系统定义的进程打开的最大文件描述符个数。因而epoll 被称为解决 C10K 问题的利器。 插个题外话网上文章不少说epoll_wait 返回时对于就绪的事件epoll 使用的是共享内存的方式即用户态和内核态都指向了就绪链表所以就避免了内存拷贝消耗。 这是错的看过 epoll 内核源码的都知道压根就没有使用共享内存这个玩意。你可以从下面这份代码看到 epoll_wait 实现的内核代码中调用了 __put_user 函数这个函数就是将数据从内核拷贝到用户空间。 边缘触发和水平触发 epoll 支持两种事件触发模式分别是边缘触发edge-triggeredET和水平触发level-triggeredLT。 这两个术语还挺抽象的其实它们的区别还是很好理解的。 使用边缘触发模式时当被监控的 Socket 描述符上有可读事件发生时服务器端只会从 epoll_wait 中苏醒一次即使进程没有调用 read 函数从内核读取数据也依然只苏醒一次因此我们程序要保证一次性将内核缓冲区的数据读取完 使用水平触发模式时当被监控的 Socket 上有可读事件发生时服务器端不断地从 epoll_wait 中苏醒直到内核缓冲区数据被 read 函数读完才结束目的是告诉我们有数据需要读取 举个例子你的快递被放到了一个快递箱里如果快递箱只会通过短信通知你一次即使你一直没有去取它也不会再发送第二条短信提醒你这个方式就是边缘触发如果快递箱发现你的快递没有被取出它就会不停地发短信通知你直到你取出了快递它才消停这个就是水平触发的方式。 这就是两者的区别水平触发的意思是只要满足事件的条件比如内核中有数据需要读就一直不断地把这个事件传递给用户而边缘触发的意思是只有第一次满足条件的时候才触发之后就不会再传递同样的事件了。 如果使用水平触发模式当内核通知文件描述符可读写时接下来还可以继续去检测它的状态看它是否依然可读或可写。所以在收到通知后没必要一次执行尽可能多的读写操作。 如果使用边缘触发模式I/O 事件发生时只会通知一次而且我们不知道到底能读写多少数据所以在收到通知后应尽可能地读写数据以免错失读写的机会。因此我们会循环从文件描述符读写数据那么如果文件描述符是阻塞的没有数据可读写时进程会阻塞在读写函数那里程序就没办法继续往下执行。所以边缘触发模式一般和非阻塞 I/O 搭配使用程序会一直执行 I/O 操作直到系统调用如 read 和 write返回错误错误类型为 EAGAIN 或 EWOULDBLOCK。 一般来说边缘触发的效率比水平触发的效率要高因为边缘触发可以减少 epoll_wait 的系统调用次数系统调用也是有一定的开销的的毕竟也存在上下文的切换。 select/poll 只有水平触发模式epoll 默认的触发模式是水平触发但是可以根据应用场景设置为边缘触发模式。 另外使用 I/O 多路复用时最好搭配非阻塞 I/O 一起使用Linux 手册关于 select 的内容中有如下说明 在Linux下select() 可能会将一个 socket 文件描述符报告为 “准备读取”而后续的读取块却没有。例如当数据已经到达但经检查后发现有错误的校验和而被丢弃时就会发生这种情况。也有可能在其他情况下文件描述符被错误地报告为就绪。因此在不应该阻塞的 socket 上使用 O_NONBLOCK 可能更安全。 简单点理解就是多路复用 API 返回的事件并不一定可读写的如果使用阻塞 I/O 那么在调用 read/write 时则会发生程序阻塞因此最好搭配非阻塞 I/O以便应对极少数的特殊情况。 总结 最基础的 TCP 的 Socket 编程它是阻塞 I/O 模型基本上只能一对一通信那为了服务更多的客户端我们需要改进网络 I/O 模型。 比较传统的方式是使用多进程/线程模型每来一个客户端连接就分配一个进程/线程然后后续的读写都在对应的进程/线程这种方式处理 100 个客户端没问题但是当客户端增大到 10000 个时10000 个进程/线程的调度、上下文切换以及它们占用的内存都会成为瓶颈。 为了解决上面这个问题就出现了 I/O 的多路复用可以只在一个进程里处理多个文件的 I/OLinux 下有三种提供 I/O 多路复用的 API分别是select、poll、epoll。 select 和 poll 并没有本质区别它们内部都是使用「线性结构」来存储进程关注的 Socket 集合。 在使用的时候首先需要把关注的 Socket 集合通过 select/poll 系统调用从用户态拷贝到内核态然后由内核检测事件当有网络事件产生时内核需要遍历进程关注 Socket 集合找到对应的 Socket并设置其状态为可读/可写然后把整个 Socket 集合从内核态拷贝到用户态用户态还要继续遍历整个 Socket 集合找到可读/可写的 Socket然后对其处理。 很明显发现select 和 poll 的缺陷在于当客户端越多也就是 Socket 集合越大Socket 集合的遍历和拷贝会带来很大的开销因此也很难应对 C10K。 epoll 是解决 C10K 问题的利器通过两个方面解决了 select/poll 的问题。 epoll 在内核里使用「红黑树」来关注进程所有待检测的 Socket红黑树是个高效的数据结构增删改一般时间复杂度是 O(logn)通过对这棵黑红树的管理不需要像 select/poll 在每次操作时都传入整个 Socket 集合减少了内核和用户空间大量的数据拷贝和内存分配。 epoll 使用事件驱动的机制内核里维护了一个「链表」来记录就绪事件只将有事件发生的 Socket 集合传递给应用程序不需要像 select/poll 那样轮询扫描整个集合包含有和无事件的 Socket 大大提高了检测的效率。 而且epoll 支持边缘触发和水平触发的方式而 select/poll 只支持水平触发一般而言边缘触发的方式会比水平触发的效率高。
http://www.hkea.cn/news/14452409/

相关文章:

  • 北京微信网站制作做计算机题目的网站
  • 外贸网站建设报价杭州网络推广有限公司
  • 免费企业网络推广网站物流公司网页设计
  • 怎么查网站是哪家公司做的网站文章超链接怎么做
  • 松江泖港网站建设山西营销型网站联系方式
  • 北京时间网站建设专业的网站开发公司
  • 建站工具免费想做网络营销推广
  • 乐都企业网站建设哪家好高端网页设计培训学校
  • 网站和app可以做充值余额功能西安网站维护兼职
  • 免费的在线设计网站泉州网站建设推广服务
  • 建网站免费空间我自己做网站
  • 成都网站建设学习嘉兴企业网络营销推广平台
  • 网站ui界面设计软件江苏泰州海陵区建设局网站
  • 网站地图对网站有什么意义厦门知名做企业网站设计的公司
  • 河北省建设工程招标投标网站网站建设的建议例子
  • 柳州网站制作公司飞凡网站建设
  • 代理网站备案2345网址导航怎么彻底删掉
  • 沧州网站的公众号网站设计的企业
  • 简单的网站怎么做朋友圈软文范例
  • 网站建设费入什么科目2018网站开发税率多少钱
  • 太原网站科技公司备案中心查网站
  • 网站制作公司代理php是前端还是后端
  • 好看动漫网替代网站淘宝店
  • 网站开发一个页面多少钱企业文化学习心得
  • 企业网站管理系统安装教程网站栏目划分
  • 楚雄网站设计网站建设和网络推广方案
  • 广州网站建设索王道下拉水泵行业网站怎么做
  • 平台网站做等级保护测评ui设计专业
  • 大唐网站建设没有服务器怎么做网站
  • 苏州专业网站建设设计公司无形资产 网站开发