热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

前段时间在忙着学校的期中考试导致博客跟新暂停了。根据前面所说的我们能够实现一个服务器端服务多个客户端的请求(每来一个客户端,我的服务器端就开一个进程去作

前段时间在忙着学校的期中考试导致博客跟新暂停了。
        根据前面所说的我们能够实现一个服务器端服务多个客户端的请求(每来一个客户端,我的服务器端就开一个进程去作相应的处理。)这种实现并发服务器的方法恢复出很大的代价的(需要大量的运算和内存空间,这是因为没每个进程都具有独立的内存空间),所以我们不会推荐使用。
        所以我们接下来要了解的就是,当客户端发送请求时,不在创建进程去一对一的服务。这也就是我们后面(很长一段时间要介绍的)的博客要了解的I/O复用技术。
        说通俗一点就是,现在我的服务器端不在一直关注是否有客户端请求连接了,而是把请求连接(还有读写等操作请求) 交给内核来监听,只有相对应的事件发生时,内核才会通知服务器端,然后服务器端来做相应的处理。大家也可以看下面的解释来理解
在这里插入图片描述
所以我们就开始我们的 I/O复用之路吧:
select实现并发服务器端
因为 select函数具有很好的移植性,而且也是最具代表性的实现复用服务器端的方法,锁以我们就先介绍它。
select函数的功能和调用顺序:
使用 select 函数时,可以将多个文件描述符集中到一起监听.


  • 是否存在套接字接收数据?
  • 无需阻塞传输数据的套接字有哪些?
  • 那些套接字发生了异常?

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

#include
#includeint 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 函数之前我们是这样来处里多个客户端发送请求的:
在这里插入图片描述
在这里插入图片描述
相信应该明白了吧,有了 select函数之后我们就能让内核去监听是否有请求,如果有的话就通知我们的服务器去做相关处理即可。

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

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

大家可以根据下面的图片来理解,因为解释的很清楚了,博主就不在自己画图
在这里插入图片描述
查阅书中的代码:
在这里插入图片描述

在这里插入图片描述
select函数的用法其实就差不多是这种用用法了。


  1. 设置 集合
  2. 初始化
  3. 添加监听事件
  4. 判断select的返回值
  5. 判断我们监听的事件是否存在

推荐阅读
  • 本指南介绍了如何在ASP.NET Web应用程序中利用C#和JavaScript实现基于指纹识别的登录系统。通过集成指纹识别技术,用户无需输入传统的登录ID即可完成身份验证,从而提升用户体验和安全性。我们将详细探讨如何配置和部署这一功能,确保系统的稳定性和可靠性。 ... [详细]
  • 线程能否先以安全方式获取对象,再进行非安全发布? ... [详细]
  • 在 Linux 环境下,多线程编程是实现高效并发处理的重要技术。本文通过具体的实战案例,详细分析了多线程编程的关键技术和常见问题。文章首先介绍了多线程的基本概念和创建方法,然后通过实例代码展示了如何使用 pthreads 库进行线程同步和通信。此外,还探讨了多线程程序中的性能优化技巧和调试方法,为开发者提供了宝贵的实践经验。 ... [详细]
  • 在《Linux高性能服务器编程》一书中,第3.2节深入探讨了TCP报头的结构与功能。TCP报头是每个TCP数据段中不可或缺的部分,它不仅包含了源端口和目的端口的信息,还负责管理TCP连接的状态和控制。本节内容详尽地解析了TCP报头的各项字段及其作用,为读者提供了深入理解TCP协议的基础。 ... [详细]
  • Java Socket 关键参数详解与优化建议
    Java Socket 的 API 虽然被广泛使用,但其关键参数的用途却鲜为人知。本文详细解析了 Java Socket 中的重要参数,如 backlog 参数,它用于控制服务器等待连接请求的队列长度。此外,还探讨了其他参数如 SO_TIMEOUT、SO_REUSEADDR 等的配置方法及其对性能的影响,并提供了优化建议,帮助开发者提升网络通信的稳定性和效率。 ... [详细]
  • 在Android平台中,播放音频的采样率通常固定为44.1kHz,而录音的采样率则固定为8kHz。为了确保音频设备的正常工作,底层驱动必须预先设定这些固定的采样率。当上层应用提供的采样率与这些预设值不匹配时,需要通过重采样(resample)技术来调整采样率,以保证音频数据的正确处理和传输。本文将详细探讨FFMpeg在音频处理中的基础理论及重采样技术的应用。 ... [详细]
  • 当使用 `new` 表达式(即通过 `new` 动态创建对象)时,会发生两件事:首先,内存被分配用于存储新对象;其次,该对象的构造函数被调用以初始化对象。为了确保资源管理的一致性和避免内存泄漏,建议在使用 `new` 和 `delete` 时保持形式一致。例如,如果使用 `new[]` 分配数组,则应使用 `delete[]` 来释放内存;同样,如果使用 `new` 分配单个对象,则应使用 `delete` 来释放内存。这种一致性有助于防止常见的编程错误,提高代码的健壮性和可维护性。 ... [详细]
  • PHP预处理常量详解:如何定义与使用常量 ... [详细]
  • 本文详细介绍了定时器输入捕捉技术的原理及其应用。通过配置定时器通道的引脚模式为输入模式,并设置相应的捕获触发条件,可以实现对外部信号的精确捕捉。该技术在实时控制系统中具有广泛的应用,如电机控制、频率测量等场景。文中还提供了具体的配置步骤和示例代码,帮助读者更好地理解和应用这一技术。 ... [详细]
  • Codeforces 605C:Freelancer's Dreams —— 凸包算法解析与题解分析 ... [详细]
  • 链栈虽然通常以数组作为底层实现,但也可以采用链表来构建Stack类。在这种情况下,空堆栈通过NULL指针表示。当新元素被压入堆栈时,它会被添加到链表的头部,从而实现高效的入栈操作。此外,出栈操作则通过移除链表头部的节点来完成,确保了操作的时间复杂度为O(1)。这种设计不仅简化了内存管理,还提高了动态数据处理的灵活性。 ... [详细]
  • 单链表的高效遍历及性能优化策略
    本文探讨了单链表的高效遍历方法及其性能优化策略。在单链表的数据结构中,插入操作的时间复杂度为O(n),而遍历操作的时间复杂度为O(n^2)。通过在 `LinkList.h` 和 `main.cpp` 文件中对单链表进行封装,我们实现了创建和销毁功能的优化,提高了单链表的使用效率。此外,文章还介绍了几种常见的优化技术,如缓存节点指针和批量处理,以进一步提升遍历性能。 ... [详细]
  • 在洛谷 P1344 的坏牛奶追踪问题中,第一问要求计算最小割,而第二问则需要找到割边数量最少的最小割。通过为每条边附加一个单位权值,可以在求解最小割时优先选择边数较少的方案,从而同时解决两个问题。这种策略不仅简化了问题的求解过程,还确保了结果的最优性。 ... [详细]
  • 如何精通编程语言:全面指南与实用技巧
    如何精通编程语言:全面指南与实用技巧 ... [详细]
  • 手指触控|Android电容屏幕驱动调试指南
    手指触控|Android电容屏幕驱动调试指南 ... [详细]
author-avatar
小小号号--
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有