请选择 进入手机版 | 继续访问电脑版

默认
打赏 发表评论 10
想开发IM:买成品怕坑?租第3方怕贵?找开源自已撸?尽量别走弯路了... 找站长给点建议
从根上理解高性能、高并发(三):深入操作系统,彻底理解I/O多路复用
微信扫一扫关注!

本文原题“终于明白了,一文彻底理解I/O多路复用”,本次收录已征得作者同意,转载请联系作者(见“2、本文作者”一节)。即时通讯网收录时有少许改动。


1、系列文章引言


1.1文章目的


作为即时通讯技术的开发者来说,高性能、高并发相关的技术概念早就了然与胸,什么线程池、零拷贝、多路复用、事件驱动、epoll等等名词信手拈来,又或许你对具有这些技术特征的技术框架比如:Java的Netty、Php的workman、Go的gnet等熟练掌握。但真正到了面视或者技术实践过程中遇到无法释怀的疑惑时,方知自已所掌握的不过是皮毛。

返璞归真、回归本质,这些技术特征背后的底层原理到底是什么?如何能通俗易懂、毫不费力真正透彻理解这些技术背后的原理,正是《从根上理解高性能、高并发》系列文章所要分享的

1.2文章源起


我(Jack Jiang)为即时通讯网整理了相当多有关IM、消息推送等即时通讯技术相关的资源和文章,从最开始的开源IM框架MobileIMSDK,到网络编程经典巨著《TCP/IP详解》的在线版本,再到IM开发纲领性文章《新手入门一篇就够:从零开发移动端IM》,以及网络编程由浅到深的《网络编程懒人入门》、《脑残式网络编程入门》、《高性能网络编程》、《不为人知的网络编程》系列文章。

越往知识的深处走,越觉得对即时通讯技术了解的太少。于是后来,为了让开发者门更好地从基础电信技术的角度理解网络(尤其移动网络)特性,我跨专业收集整理了《IM开发者的零基础通信技术入门》系列高阶文章。这系列文章已然是普通即时通讯开发者的网络通信技术知识边界,加上之前这些网络编程资料,解决网络通信方面的知识盲点基本够用了。

对于即时通讯IM这种系统的开发来说,网络通信知识确实非常重要,但回归到技术本质,实现网络通信本身的这些技术特征:包括上面提到的线程池、零拷贝、多路复用、事件驱动等等,它们的本质是什么?底层原理又是怎样?这就是整理本系列文章的目的,希望对你有用

1.3文章目录



1.4本篇概述


接上篇《深入操作系统,理解I/O与零拷贝技术》,本篇是高性能、高并发系列的第3篇文章,上篇里我们讲到了I/O技术,本篇将以更具象的文件这个话题入手,带你一步步理解高性能、高并发服务端编程时无法回避的I/O多路复用及相关技术。

本文已同步发布于“即时通讯技术圈”公众号,欢迎关注。公众号上的链接是:点此进入

2、本文作者


应作者要求,不提供真名,也不提供个人照片。

本文作者主要技术方向为互联网后端、高并发高性能服务器、检索引擎技术,网名是“码农的荒岛求生”,公众号“码农的荒岛求生”。感谢作者的无私分享。

3、什么是文件?


在正式展开本文的内容之前,我们需要先预习一下文件以及文件描述符的概念。

程序员使用I/O最终都逃不过文件这个概念。

在Linux世界中文件是一个很简单的概念,作为程序员我们只需要将其理解为一个N byte的序列就可以了:

b1, b2, b3, b4, ....... bN


实际上所有的I/O设备都被抽象为了文件这个概念,一切皆文件(Everything is File),磁盘、网络数据、终端,甚至进程间通信工具管道pipe等都被当做文件对待。

1.png

所有的I/O操作也都可以通过文件读写来实现,这一非常优雅的抽象可以让程序员使用一套接口就能对所有外设I/O操作

常用的I/O操作接口一般有以下几类:

  • 1)打开文件,open;
  • 2)改变读写位置,seek;
  • 3)文件读写,read、write;
  • 4)关闭文件,close。

程序员通过这几个接口几乎可以实现所有I/O操作,这就是文件这个概念的强大之处。

4、什么是文件描述符?


在上一篇《深入操作系统,理解I/O与零拷贝技术》中我们讲到:要想进行I/O读操作,像磁盘数据,我们需要指定一个buff用来装入数据。

一般都是这样写的:

read(buff);


但是这里我们忽略了一个关键问题:那就是,虽然我们指定了往哪里写数据,但是我们该从哪里读数据呢?

从上一节中我们知道,通过文件这个概念我们能实现几乎所有I/O操作,因此这里少的一个主角就是文件

那么我们一般都怎样使用文件呢?

举个例子:如果周末你去比较火的餐厅吃饭应该会有体会,一般周末人气高的餐厅都会排队,然后服务员会给你一个排队序号,通过这个序号服务员就能找到你,这里的好处就是服务员无需记住你是谁、你的名字是什么、来自哪里、喜好是什么、是不是保护环境爱护小动物等等,这里的关键点就是:服务员对你一无所知,但依然可以通过一个号码就能找到你

同样的:在Linux世界要想使用文件,我们也需要借助一个号码,根据“弄不懂原则”,这个号码就被称为了文件描述符(file descriptors),在Linux世界中鼎鼎大名,其道理和上面那个排队号码一样。

因此:文件描述仅仅就是一个数字而已,但是通过这个数字我们可以操作一个打开的文件,这一点要记住。

2.png

有了文件描述符,进程可以对文件一无所知,比如文件在磁盘的什么位置、加载到内存中又是怎样管理的