实现高并发服务器之 I/O复用

简介: 前段时间在忙着学校的期中考试导致博客跟新暂停了。 根据前面所说的我们能够实现一个服务器端服务多个客户端的请求(每来一个客户端,我的服务器端就开一个进程去作相应的处理。)这种实现并发服务器的方法恢复出很大的代价的(需要大量的运算和内存空间,这是因为没每个进程都具有独立的内存空间),所以我们不会推荐使用。

前段时间在忙着学校的期中考试导致博客跟新暂停了。

       根据前面所说的我们能够实现一个服务器端服务多个客户端的请求(每来一个客户端,我的服务器端就开一个进程去作相应的处理。)这种实现并发服务器的方法恢复出很大的代价的(需要大量的运算和内存空间,这是因为没每个进程都具有独立的内存空间),所以我们不会推荐使用。

       所以我们接下来要了解的就是,当客户端发送请求时,不在创建进程去一对一的服务。这也就是我们后面(很长一段时间要介绍的)的博客要了解的I/O复用技术。

       说通俗一点就是,现在我的服务器端不在一直关注是否有客户端请求连接了,而是把请求连接(还有读写等操作请求) 交给内核来监听,只有相对应的事件发生时,内核才会通知服务器端,然后服务器端来做相应的处理。大家也可以看下面的解释来理解

20191116195140787.png

所以我们就开始我们的 I/O复用之路吧:

select实现并发服务器端

因为 select函数具有很好的移植性,而且也是最具代表性的实现复用服务器端的方法,锁以我们就先介绍它。

select函数的功能和调用顺序:

使用 select 函数时,可以将多个文件描述符集中到一起监听.


  • 是否存在套接字接收数据?


  • 无需阻塞传输数据的套接字有哪些?


  • 那些套接字发生了异常?


select 函数使用方法与我们平时使用的函数有很大的区别,他比较难使用,所以博主现在这里给出 select 函数


#include<sys/select.h>
#include<sys/time.h>
int select(int maxfd, fd_set *readset, fd_set *writeset, fd_set *exceptset,
      const struct timeval *timeout);
参数:
  第一个参数: int maxfd 
    ----> 监控对象文件描述符的最大数量,也就是监控的文件描述符集里最大文件描述符加1
          书上写的是监视对象文件描述符数量(我觉得描述的不是很准确)
  第二个参数: fd_set *readset 
    ----> 监控是否有读数据到达文件描述符集合(fd_set 定义的集合),传入传出参数
      书上: 将所有关注“是否存在待读取数据”的文件描述符注册到 fd_set型变量(这里理解为集合会好一点),并传递其地址值。
  第三个参数:fd_set *writeset
    ----> 监控写数据到达文件描述符集合,传入传出参数
  第四个参数:fd_set *exceptset
    ----> 监控异常发生达文件描述符集合,如带外数据到达异常,传入传出参数
  第五个参数:const struct timeval *timeout
    ---->定时阻塞的监控时间,分成3种情况
        1.NULL,永远阻塞
        2.设置timeval,等待固定时间
        3.设置timeval里时间均为0,检查描述字后立即返回,轮询
    我们来看一看第五个参数的 结构体长什么样子
    struct timeval 
    {
      long tv_sec; /* seconds */
      long tv_usec; /* microseconds */
    };  
返回值:(返回值也比较复杂,会引出另外四个函数,博主会解释的)
    发生错误:-1
    超时:0
    因发生时间而返回时,返回大于 0 的值,这个值就是满足我们监听的事件个数!!!
      (虽然返回了有几个事件满足监听,但是我们却不知道是哪几个事件满足,所以就会引出后面的四个函数来判断是那些事件满足)。

如果只看文字那么一定是非常枯燥的,所以博主再讲解后面更枯燥的内容之前先对比下我们这篇博客到底要做的是什么吧,也正好缓解下刚刚看select函数复杂的心情。


使用 select 函数之前我们是这样来处里多个客户端发送请求的:

20191116202654291.png

2019111620404845.png

相信应该明白了吧,有了 select函数之后我们就能让内核去监听是否有请求,如果有的话就通知我们的服务器去做相关处理即可。


我们假设客户端有三个请求发送过来,根据我们上面所讲到的,select会返回3,但是你知道是哪三个发送的请求吗?这就感到疑惑了对吧?也就是为了解决我们的疑问,所以我们接下来来介绍: 调用select函数之后如何产看结果的技术:

  void FD_ZERO(fd_set *set);      //把文件描述符集合里所有位清0
  void FD_SET(int fd, fd_set *set);   //把文件描述符集合里fd位置1
  void FD_CLR(int fd, fd_set *set);   //把对应的文件描述清除,也就是把文件描述符集合里对应的fd清0
  int FD_ISSET(int fd, fd_set *set);  //查看文件描述符集合里fd是否置1

大家可以根据下面的图片来理解,因为解释的很清楚了,博主就不在自己画图

20191116205517174.png

查阅书中的代码:

       20191116210649154.png                        

20191116211021586.png

select函数的用法其实就差不多是这种用用法了。


  1. 设置 集合


  1. 初始化


  1. 添加监听事件


  1. 判断select的返回值


  1. 判断我们监听的事件是否存在


目录
相关文章
|
6月前
|
API C++
socket编程之常用api介绍与socket、select、poll、epoll高并发服务器模型代码实现(1)
前言   本文旨在学习socket网络编程这一块的内容,epoll是重中之重,后续文章写reactor模型是建立在epoll之上的。
77 0
|
1月前
|
缓存 NoSQL Ubuntu
大数据-39 Redis 高并发分布式缓存 Ubuntu源码编译安装 云服务器 启动并测试 redis-server redis-cli
大数据-39 Redis 高并发分布式缓存 Ubuntu源码编译安装 云服务器 启动并测试 redis-server redis-cli
53 3
|
1月前
|
Java Linux
【网络】高并发场景处理:线程池和IO多路复用
【网络】高并发场景处理:线程池和IO多路复用
39 2
|
2月前
|
网络协议 Java Linux
高并发编程必备知识IO多路复用技术select,poll讲解
高并发编程必备知识IO多路复用技术select,poll讲解
|
2月前
|
网络协议 数据处理 C语言
利用C语言基于poll实现TCP回声服务器的多路复用模型
此代码仅为示例,展示了如何基于 `poll`实现多路复用的TCP回声服务器的基本框架。在实际应用中,你可能需要对其进行扩展或修改,以满足具体的需求。
78 0
|
3月前
|
数据采集 资源调度 JavaScript
Node.js 适合做高并发、I/O密集型项目、轻量级实时应用、前端构建工具、命令行工具以及网络爬虫和数据处理等项目
【8月更文挑战第4天】Node.js 适合做高并发、I/O密集型项目、轻量级实时应用、前端构建工具、命令行工具以及网络爬虫和数据处理等项目
55 5
|
6月前
|
监控 安全 Linux
socket编程之常用api介绍与socket、select、poll、epoll高并发服务器模型代码实现(3)
高并发服务器模型-poll poll介绍   poll跟select类似, 监控多路IO, 但poll不能跨平台。其实poll就是把select三个文件描述符集合变成一个集合了。
73 0
|
6月前
|
前端开发 Java API
构建异步高并发服务器:Netty与Spring Boot的完美结合
构建异步高并发服务器:Netty与Spring Boot的完美结合
|
6天前
|
弹性计算
阿里云2核16G服务器多少钱一年?亲测价格查询1个月和1小时收费标准
阿里云2核16G服务器提供多种ECS实例规格,内存型r8i实例1年6折优惠价为1901元,按月收费334.19元,按小时收费0.696221元。更多规格及详细报价请访问阿里云ECS页面。
38 9

热门文章

最新文章

  • 1
    高并发场景下,到底先更新缓存还是先更新数据库?
    59
  • 2
    Java面试题:解释Java NIO与BIO的区别,以及NIO的优势和应用场景。如何在高并发应用中实现NIO?
    66
  • 3
    Java面试题:设计一个线程安全的单例模式,并解释其内存占用和垃圾回收机制;使用生产者消费者模式实现一个并发安全的队列;设计一个支持高并发的分布式锁
    64
  • 4
    Java面试题:如何实现一个线程安全的单例模式,并确保其在高并发环境下的内存管理效率?如何使用CyclicBarrier来实现一个多阶段的数据处理任务,确保所有阶段的数据一致性?
    56
  • 5
    Java面试题:结合建造者模式与内存优化,设计一个可扩展的高性能对象创建框架?利用多线程工具类与并发框架,实现一个高并发的分布式任务调度系统?设计一个高性能的实时事件通知系统
    51
  • 6
    Java面试题:假设你正在开发一个Java后端服务,该服务需要处理高并发的用户请求,并且对内存使用效率有严格的要求,在多线程环境下,如何确保共享资源的线程安全?
    66
  • 7
    在Java中实现高并发的数据访问控制
    39
  • 8
    使用Java构建一个高并发的网络服务
    26
  • 9
    微服务06----Eureka注册中心,微服务的两大服务,订单服务和用户服务,订单服务需要远程调用我们的用,户服务,消费者,如果环境改变,硬编码问题就会随之产生,为了应对高并发,我们可能会部署成一个集
    36
  • 10
    如何设计一个秒杀系统,(高并发高可用分布式集群)
    122