非阻塞IO服务器模型

我们来考虑一个情形,你跟千千万万个玩家是魔兽世界的超级粉丝,每周末准时组团打boss。每当周末游戏服务器就亚历山大,因为起码几十万用户同时在线。如果用我们的多线程阻塞服务器作为游戏服务器是否可行呢?先分析游戏服务器有哪些特点:

①  网络游戏并非像网页一样,打开一旦下载完就可以关闭连接结束。网游必须是有一个持久有状态的连接,每一个客户端都需要跟服务器存在一个持久的连接,以便快速及时发送消息。而随着并发用户数量的增加,多线程阻塞服务器不可能为每一个客户端分配一个线程。

②  跟一般的应用服务器不同,CS结构的网络游戏一般把复杂的逻辑处理放到了客户端,而在游戏服务器端只处理比较简单的逻辑,甚至只是传递消息。像这样简单的逻辑我们竟然给每一个请求分配一条线程,这是不是严重脱离实际了?

③  网游讲求的是响应快,消息交换及时,并且能进行双向通信,那必然需要频繁请求跟响应,假如我们已经采用了长久连接,但服务器并不是每次都有新数据,并不需要发送给客户端,那我们还占了一条线程,是不是太浪费了?

从以上几点分析,像网游这样的场合,我们传统的多线程服务器显然已经力不从心。线程池能在一定程度上缓解频繁的IO调用带来的资源占用,但池有一定的大小限制,在面对成千上万的客户端请求大并发情况下,却始终不是最佳方案。有没有可能用一个或少量的线程就可以维护很多持久连接呢?下面介绍一种新的服务器模型——非阻塞服务器模型。

非阻塞服务器模型最重要的一个特点是,在调用某个接口后立即返回,而不会阻塞等待。如图2-6-2-1中所展示,当多个客户端向服务器请求时,服务器端会保存一个socket连接列表,然后有一个专门的线程对这个列表进行轮询。如果发现某个socket有数据可读,就调用该socket的相应的读操作;反之,发现socket有数据可写的话,就调用该socket的相应的写操作;如果发现某个socket已经中断,就调用socket关闭操作。为了有更好地性能,还可以结合线程池,一旦检测到有需要处理(读数据、写数据、关闭)的socket就启动另外一条线程负责处理。

图2-6-2-1 非阻塞服务器模型

这样看来,不管多少个socket连接都可以被一条线程管理起来,一条线程负责遍历这些socket列表,处理再交给线程池,很好地利用了阻塞的时间,处理能力得到提升。但这种模型涉及到遍历所有的socket列表,同时需要处理数据的拼接,空闲时也占用较多CPU资源,仍然不适于大并发场景。再稍做改进——事件驱动模型。它的核心是事件驱动,线程遍历的并非socket列表,取而代之的是检测事件,对检测出来的事件进行逐一响应。极大提高了检测效率,自然处理能力也更强。

非阻塞IO服务器模型,布布扣,bubuko.com

时间: 2024-10-12 22:11:15

非阻塞IO服务器模型的相关文章

从操作系统内核看Java非阻塞IO事件检测

非阻塞服务器模型最重要的一个特点是,在调用读取或写入接口后立即返回,而不会进入阻塞状态.在探讨单线程非阻塞IO模型前必须要先了解非阻塞情况下Socket事件的检测机制,因为对于非阻塞模式最重要的事情是检测哪些连接有感兴趣的事件发生,一般会有如下三种检测方式. 应用程序遍历socket检测 如图所示,当多个客户端向服务器请求时,服务器端会保存一个socket连接列表,应用层线程对socket列表进行轮询尝试读取或写入.对于读取操作,如果成功读取到若干数据则对读取到的数据进行处理,读取失败则下个循环

Nginx:异步非阻塞IO

在使用socket编程中,经常会看到阻塞.非阻塞.同步.异步,那么它们之间到底有什么关系跟区别呢? 本次将那Nginx的异步非阻塞的事件驱动模型来解释一下它们之间的关系. 阻塞IO 在linux中,默认所有socket都是阻塞的. 这意味着使用该socket调用诸如recv的函数时,在没有数据到达之前,该函数将不会返回,导致线程被阻塞,直到数据到达. 非阻塞IO 我们可以使用fcntl把socket设置为非阻塞的. 这意味着使用该socket调用诸如recv的函数时,该函数将立刻返回,可以根据返

阻塞IO,非阻塞IO,异步IO和非异步IO 的区别

最近在研究java IO.NIO.NIO2(或者称AIO)相关的东西,有些概念还是要明确下. 按照<Unix网络编程>的划分,IO模型可以分为:阻塞IO.非阻塞IO.IO复用.信号驱动IO和异步IO,按照POSIX标准来划分只分为两类:同步IO和异步IO. 如何区分呢?首先一个IO操作其实分成了两个步骤: 1.发起IO请求 2.实际的IO操作 阻塞和非阻塞IO:在于第一个步骤是否会会被阻塞,如果会则是阻塞IO,否则是非阻塞IO. 异步和非异步(同步)IO:在于第二个步骤是否会阻塞,如果实际的I

Java中的阻塞和非阻塞IO包各自的优劣思考

NIO 设计背后的基石:反应器模式,用于事件多路分离和分派的体系结构模式. 反应器(Reactor):用于事件多路分离和分派的体系结构模式 通常的,对一个文件描述符指定的文件或设备, 有两种工作方式: 阻塞 与非阻塞 .所谓阻塞方式的意思是指, 当试图对该文件描述符进行读写时, 如果当时没有东西可读,或者暂时不可写, 程序就进入等待 状态, 直到有东西可读或者可写为止.而对于非阻塞状态, 如果没有东西可读, 或者不可写, 读写函数马上返回, 而不会等待 . 一种常用做法是:每建立一个Socket

阻塞IO服务器模型之多线程服务器模型

针对单线程服务器模型的特点,我们可以对其进行改进,使之能对多个客户端同时进行响应.最简单的改进即是使用多线程(或多进程)服务器模型,在应用层级别,我们一般采用多线程模式.多线程能让多个客户端同时请求,并能几乎同时对这些请求进行响应,而不用排队一个一个处理,能同时为多个客户端提供一问一答的服务. 图2-6-1-2 多线程阻塞服务器模型 多线程服务器模型核心就是利用多线程机制,为每个客户端分配一个线程.如图2-6-1-2,服务器初始化一个Serversocket实例,绑定某个端口号,并使之监听客户端

阻塞IO服务器模型之单线程服务器模型

单线程服务器模型是最简单的一个服务器模型,几乎我们所有程序员在刚开始接触网络编程(不管是B/S结构还是C/S结构)都是从这个简单的模型开始.这种模型只提供同时一个客户端访问,多个客户端访问必须要等到前一个客户端访问结束,一个一个排队,即提供一问一答服务. 图2-6-1-1 单线程阻塞服务器模型 图2-6-1-1展示了单线程阻塞服务器是怎样响应客户端的访问.首先,服务器必须初始化一个Serversocket实例,绑定某个端口号,并使之监听客户端的访问,以此提供一种服务.接着客户端1远程调用服务器的

阻塞与非阻塞IO -- 网络编程随想

阻塞和非阻塞IO 阻塞IO指当进行IO操作时, 如果IO操作无法立即完成,当前线程进入阻塞状态,直到IO操作完成,IO函数返回. 非阻塞IO指当进行IO操作时,如果IO操作无法立即完成,IO函数立即返回,线程不会阻塞. 写与读操作对阻塞与非阻塞IO的语义 写操作,只有完成所有指定数据的写入时,写操作才算完成. 读操作,只要能读取到数据,读操作就算完成. 阻塞IO 写操作.len 为指定写入的数据量. 如果只写入部分数据,IO函数会阻塞直至写入数据或发生错误才返回. 以soket的send()为例

实例浅析epoll的水平触发和边缘触发,以及边缘触发为什么要使用非阻塞IO

一.基本概念                                                          我们通俗一点讲: Level_triggered(水平触发):当被监控的文件描述符上有可读写事件发生时,epoll_wait()会通知处理程序去读写.如果这次没有把数据一次性全部读写完(如读写缓冲区太小),那么下次调用 epoll_wait()时,它还会通知你在上没读写完的文件描述符上继续读写,当然如果你一直不去读写,它会一直通知你!!!如果系统中有大量你不需要读写的就

转一贴,今天实在写累了,也看累了--【Python异步非阻塞IO多路复用Select/Poll/Epoll使用】

下面这篇,原理理解了, 再结合 这一周来的心得体会,整个框架就差不多了... http://www.haiyun.me/archives/1056.html 有许多封装好的异步非阻塞IO多路复用框架,底层在linux基于最新的epoll实现,为了更好的使用,了解其底层原理还是有必要的.下面记录下分别基于Select/Poll/Epoll的echo server实现.Python Select Server,可监控事件数量有限制: 1 2 3 4 5 6 7 8 9 10 11 12 13 14