NIO

Tcp 的网络模型

  • socket 创建套接字,他是系统给应用程序的一个文件描述符
  • 对系统的bind,绑定地址和端口号
  • 系统调用listen创建一个队列用于存放客户端进来的连接
  • 最后使用accep进行连接请求。

堵塞式的IO

在socket默认状态之下堵塞的,主要有三种堵塞:

  • connect 阻塞:
    当客户的发起TCP请求,是通过connect函数,使用TCP连接建立的需要完成三次握手过程。在ack和syn信号需要堵塞等待。

  • Accept阻塞,一个堵塞的socket通信的服务端接受外来连接,会调用accept,没有新的连接到达,调用进程会将你过期。

  • read,write 堵塞,当一个sock创建成功之后,度无端用fork函数创建一个子进程,调用read函数等待客户端的数据写入,如果没有数据写入没调用子进程挂起,进入堵塞状态。

非堵塞式IO

使用fcntl可以把以上三种方式设置为为非堵塞状态。如果没有数据返回,就会直接返回一个EWOULDBLOCK 或 EAGAIN 错误。

当我们把以上操作设置为了非堵塞状态,需要一个线程会该操作进行轮询检查。

IO复用

用一个线程进行进行三种状态的轮询对于大量请求情况下,对cpu而言是一总灾难。

Linux 提供了IO复用函数select、poll、epoll,进程将一个或者多个读操作通过系统调用函数堵塞在函数操作欧尚。使用系统内核见识读操作是否就绪。

select函数

在超时时间内,监听用户感兴趣文件描述符上的可读可写和异常时间的发生。Linux内核把所有的外部设备看做是一个文件来操作,对于一个文件的读写操作会调用内核提供的系统命令,返回一个文件描述符。

 int select(int maxfdp1,fd_set *readset,fd_set *writeset,fd_set *exceptset,const struct timeval *timeout)
 int select(int maxfdp1,fd_set *readset,fd_set *writeset,fd_set *exceptset,const struct timeval *timeout)

select 函数监视文件描述符就绪或者超时,函数返回。当select函数返回后,通过FD_ISSET遍历fdset,找到这个描述符。「其中fd_set可以理解为一个集合,这个集合中存放的是文件描述符,可以通过四个宏获得」


          void FD_ZERO(fd_set *fdset);           // 清空集合
          void FD_SET(int fd, fd_set *fdset);   // 将一个给定的文件描述符加入集合之中
          void FD_CLR(int fd, fd_set *fdset);   // 将一个给定的文件描述符从集合中删除
          int FD_ISSET(int fd, fd_set *fdset);   // 检查集合中指定的文件描述符是否可以读写 

poll函数

在每次调用select函数之前,系统需要把fd从用户态拷贝到内核态,这会对系统带来一定的开销。对于单个进程监视的fd数量默认是1024,我们可以通过修改宏定义甚至重新编译内核的方式打破这一限制。对于fd_set是基于数组实现的,在add和delete
fd的时候,数量过大效率降低。

poll 和 select 的区别联系

poll 和select 存在一个相同的缺点是需要拷贝文件描述符被整体赋值到用户态和内核态之间,而无论这些这些文件是都准备就绪,他们开销就会随着文件描述符数量线程增大。(poll监视的文件符没有select 的1024数量的限制,但是由于他会把fd拷贝到内核态,会带来一定开销)

epoll 函数

select / poll 是顺序扫描fd是否就绪,而且支持的fd数量不宜过大,因此会有制约。

对于epoll,使用的是事件驱动的方式代替轮询扫描fd。epoll事先通过epoll_ctl()来注册一个文件描述符,将文件描述符存放到内核的一个时间表中,这个时间表基于红黑树实现,所以在大量的IO请求场景下,插入和删除的性能会比前两个号。因此,epoll的性能更好,不受到fd数量的限制。


          void FD_ZERO(fd_set *fdset);           // 清空集合
          void FD_SET(int fd, fd_set *fdset);   // 将一个给定的文件描述符加入集合之中
          void FD_CLR(int fd, fd_set *fdset);   // 将一个给定的文件描述符从集合中删除
          int FD_ISSET(int fd, fd_set *fdset);   // 检查集合中指定的文件描述符是否可以读写 

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,200评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,526评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,321评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,601评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,446评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,345评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,753评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,405评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,712评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,743评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,529评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,369评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,770评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,026评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,301评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,732评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,927评论 2 336

推荐阅读更多精彩内容