I/O的概念
操作系统的分为socket的I/O还有用户界面的输入输出,一般一个输入操作分为两个不同的阶段,1)等待数据准备好;2)从内核向进程复制数据
从理论上来讲,阻塞I/O、非阻塞I/O、复用I/O、信号驱动I/O都是同步IO模型,异步I/O就是异步IO,同步I/O向应用程序通知的是I/O就绪事件,异步I/O向应用程序通知的是I/O完成事件。
同步和异步:都是针对应用程序和操作系统之间交互而言的。同步的话,如果上层应用不主动询问操作系统的话,操作系统是不会主动通知应用程序的。异步的话,操作系统会主动通知应用程序。
阻塞:如果条件不满足的话,操作系统将应用程序挂起或者休眠,此时应用程序处于阻塞状态,只有当数据准备好之后或者数据已经从内核空间拷贝到用户空间,操作系统通知线程,此时唤醒线程。
非阻塞:如果条件不满足的话,该方法不会阻塞当前线程,而是立即返回一个标志信息(数据还没有准备好),或者timeou之后返回,此时应用线程还可以进行其他的操作。
在linux中并不存在真正的异步I/O,而是通过多路复用I/O的方式去模拟异步IO
注意:同步并不等同于阻塞,同步调用的时候,即便调用不返回,但是应用线程还处于运行状态,可以进行其他的操作,而阻塞调用时,应用线程处于阻塞状态。
操作系统5种通信模型
  1. 阻塞I/O
解释:应用程序会调用一个IO函数,导致应用程序阻塞,程序会一直停留在此处,如果数据准备好了,内核会将数据拷贝至应用程序
伪代码:
{     read(socket, buffer);     process(buffer); }
特点:当处理socket数量较少的时候,使用阻塞式I/O比较合适,当socket数量较大,为每一个socket都分配一个读线程、处理线程以及同步的事件,那么对操作系统的开销会变得很大,并且不支持大数据量的socket链接
  1. 非阻塞I/O
解释:非阻塞IO就是通过反复调用IO函数,如果没有数据,那么会立即返回一个错误的接口,不断去调用,不断去轮询,查看是否可以获取数据,通常来说,这种比较耗费大量的cpu时间,在数据拷贝阶段,还是阻塞的,原理就是应用程序在socket非阻塞的时候,告诉操作系统,不要在没有数据的时候把我挂起或者休眠,而是返回一个错误的信号
伪代码:
{     while(read(socket, buffer) != SUCCESS)     ;     process(buffer); }
特点:不容易使用,需要编写更多的代码,如果非阻塞IO在控制建立多个连接,在数据的收发量不均,时间不定的情况下,更具优势
  1. I/O复用模型
解释:主要就是select、poll和epoll,有了I/O复用,我们可以使用select或者poll或者epoll,两次调用,两次返回,相对于阻塞I/O没有什么优越性,关键是能实现同时对多个IO端口进行监听,会使进程阻塞,可以同时阻塞多个I/O操作。
多路复用I/O模型是目前使用比较多的模型,所谓多路复用,可以理解为在一个应用线程里面可以处理多个socket连接,或者同一个端口接受来自多个客户端的请求(连接、读、写),多路复用I/O与传统的非阻塞IO的区别在于,在传统的非阻塞I/O中,是由用户去轮询socket状态,而在多路复用I/O中,由内核去轮询向select注册的socket的状态,所以多路复用IO需要操作系统的支持。
最大的优势是,在同一个线程中,可以同时处理多个socket的IO请求,在同步阻塞模型中,必须通过多线程的方式才可以达到这个目的。while循环之前,将socket添加到select监视中,然后while循环一直调用select获取被激活的socket,一旦socket可读,便调用read函数将socket中的数据读取出来。但是每个IO请求的过程还是阻塞的(在select函数上阻塞),平均时间甚至比同步阻塞IO模型还要长。
伪代码:
{     select(socket);     while(true){         sockets = select();         for(socket in sockets){             if(can_read(socket)){                 read(socket, buffer);                 process(buffer);             }         }     } }
特点:使用场景:
1)当客户处理多个描述符(通常是交互式输入和socket)时,必须使用I/O复用
2)一个客户同时处理多个socket是可能的
3)如果一个TCP服务器既要处理监听socket,又要处理已经连接的socket,一般就要使用I/O复用
4)如果一个服务器既要处理TCP,又要处理UDP,一般就要使用I/O复用
  1. 信号驱动I/O
解释:首先我们允许socket进行信号驱动I/O,并且安装一个信号处理函数,进行继续运行不阻塞,当数据准备好之后,进程收到一个SIGIO信号,可以在信号处理函数中调用I/O操作函数处理数据
特点:这种模型的优势在于等待数据包到达期间,进程不会被阻塞,只需要等待信号处理函数的通知,既可以是数据准备好被处理,也可以是数据包已经准备好被读取
  1. 异步I/O模型
解释:先异步调用,但是不会立即返回数据,而是等待被调用部件完成后,通过状态、通知和回调来通知调用者的输入输出操作,这个与信号驱动I/O的区别在于:1)信号驱动I/O是由内核通知我们如何启动一个I/O操作;2)而异步I/O模型是由内核通知我们I/O操作何时完成,异步I/O模型才是最理想的I/O模型,在异步I/O模型中,当用户线程发起read操作之后,立刻就可以开始去做其他的事情。而另外一方面,从内核的角度,当它收到asynchronous read之后,它会立刻返回,说明read请求已经成功发起,因此不会对用户线程产生任何block。然后内核会等待数据准备完成,然后将数据拷贝到用户线程,当这一切都完成之后,内核就会给用户线程发一个信号,告诉它read操作完成了。也就说用户线程完全不需要实际的整个I/O操作是如何进行的,只需要先发起一个请求,当接受内核返回成功的信号时表示I/O操作已经完成,可以直接去使用数据了,异步I/O模型中,由操作系统内核去等待数据就绪,copy数据到用户空间,用户线程始终没有阻塞。
特点:我们调用aio_read函数,给内核传递描述符、缓冲区指针,缓冲区大小和文件偏移,并告诉内核当整个操作完成的时候如何通知我们。该系统调用后就立即返回,而且在等待I/O完成期间,我们的进程不被阻塞
 
 
 
 
参考资料:

通信模型socket的更多相关文章

  1. 【招聘App】—— React/Nodejs/MongoDB全栈项目:socket.io&聊天实现

    前言:最近在学习Redux+react+Router+Nodejs全栈开发高级课程,这里对实践过程作个记录,方便自己和大家翻阅.最终成果github地址:https://github.com/66We ...

  2. 系列文章--突袭HTML5之Javascript

    突袭HTML5之Javascript API扩展5 - 其他扩展 突袭HTML5之Javascript API扩展4 - 拖拽 突袭HTML5之Javascript API扩展3 - 本地存储 突袭H ...

  3. 系列文章--突袭HTML5

    学习新的网站构建技术:基于HTML5,但不限于HTML5.   突袭HTML5之Javascript API扩展5 - 其他扩展   突袭HTML5之Javascript API扩展4 - 拖拽   ...

  4. java的nio之:java的bio流下实现的socket服务器同步阻塞模型和socket的伪异步的socket服务器的通信模型

    同步I/O模型的弊端===>每一个线程的创建都会消耗服务端内存,当大量请求进来,会耗尽内存,导致服务宕机 伪异步I/O的弊端分析===>当对Socket的输入流进行读取操作的时候,它会一直 ...

  5. 用Java socket (TCP通信模型)实现一个简单的web 服务器

    package cn.magicdu.think.socket; import java.io.OutputStream; import java.io.PrintWriter; import jav ...

  6. linux 高并发socket通信模型

    ------select 1 一个误区很多人认为它最大可以监听1024个,实际上却是文件描述符的值不能大于等于1024,所以除掉标准输入.输出.错误输出,一定少于1024个,如果在之前还打开了其他文件 ...

  7. JAVA通信系列一:Java Socket技术总结

    本文是学习java Socket整理的资料,供参考. 1       Socket通信原理 1.1     ISO七层模型 1.2     TCP/IP五层模型 应用层相当于OSI中的会话层,表示层, ...

  8. Java Socket

    什么是Socket Socket的概念很简单,它是网络上运行的两个程序间双向通讯的一端,既可以接收请求,也可以发送请求,利用它可以较为方便地编写网络上数据的传递. 所以简而言之,Socket就是进程通 ...

  9. 高性能 Socket 组件 HP-Socket v3.2.1 正式发布

    HP-Socket 是一套通用的高性能 TCP/UDP Socket 组件,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C ...

随机推荐

  1. 数据备份服务商Rubrik获4000万美元B轮融资

    搜狐科技 文/丽丽卡 5月27日,数据备份服务商Rubrik获Greylock Partners领投的4000万美元B轮融资,Lightspeed Venture Partners及其现有投资者跟投, ...

  2. 【转载】Spring Boot引起的“堆外内存泄漏”排查及经验总结

    背景 为了更好地实现对项目的管理,我们将组内一个项目迁移到MDP框架(基于Spring Boot),随后我们就发现系统会频繁报出Swap区域使用量过高的异常.笔者被叫去帮忙查看原因,发现配置了4G堆内 ...

  3. apache虚拟主机防止php网页木马vhost.conf文件配置

    <VirtualHost *> DocumentRoot "/www/www.abc.com" ServerName www.abc.com ServerAlias a ...

  4. Spring Boot2(一):使用Spring Boot2集成Mybatis基础搭建

    Mybatis 初期使用比较麻烦,需要各种配置文件.实体类.Dao 层映射关联.还有一大推其它配置.mybatis-spring-boot-starter 就是 Spring Boot+ Mybati ...

  5. Hexo+NexT(二):Hexo站点配置详解

    阅读本篇之前,假定读者已经有了Node.js的基础,如需要补充Node.js知识的,请自行百度. Hexo是在Node.js框架下的一个项目,利用Node.js提供的强大功能,完成从Markdown到 ...

  6. mpvue 试水的一天

    小程序经过了将近两年的锤炼,现在出现了许许多多的框架,来帮助我们进行快速开发,最近可能迷上了mpvue这个框架,所以就用公司的项目练练手. mpvue是用vue作为基础骨架的,所以他非常想vue,所以 ...

  7. zphp源码分析(一)

    zphp是一款轻量级的php服务端框架,是swoole官方开发的.可以用来开发web应用和网络服务. 安装: 可以通过composer安装, { "require": { &quo ...

  8. 微信小程序 CSS border-radius元素 overflow:hidden失效问题 iPhone ios 苹果兼容问题 伪类元素

    同事找我解决一个问题 说安卓圆角没问题 苹果上失效了 我一看 其实就是没做兼容上图给你们看看 有没有看出来 其实就是父级设置圆角属性失效 父元素使用border-radius和overflow:hid ...

  9. 关于Nginx499、502和504的分析

    我相信有些人在面试运维类岗位的时候会碰到对方问关于这方面的问题,我这里通过几个实验来复现这个情况,并做出相关分析,我希望大家看完后针对这种问题能有一个清晰思路. 服务器 IP Nginx 192.16 ...

  10. Redis中的Stream数据类型作为消息队列的尝试

    Redis的List数据类型作为消息队列,已经比较合适了,但存在一些不足,比如只能独立消费,订阅发布又无法支持数据的持久化,相对前两者,Redis Stream作为消息队列的使用更为有优势.   相信 ...