Linux网络编程(四)

在linux网络编程【1-3】中,咱们编写的网络程序仅仅是为了了解网络编程的基本步骤,实际应用当中的网络程序并不会用那样的。首先,若是服务器须要处理高并发访问,一般不会使用linux网络编程(三)中那样的多进程方式,由于那样至关耗系统资源。实际当中,网络程序多使用select、poll、epoll等多路IO复用来进行编写。在进入主题以前,咱们先来了解一下linux的IO模型。linux

现有的linux IO模型有5种:阻塞式IO模型,非阻塞式IO模型,IO复用模型,信号驱动式IO模型,异步IO模型编程

关于阻塞、非阻塞、同步、异步,甚至并发等待,这些概念一直没有很好的理解,特地翻阅一些资料和博文,汇总以下:服务器

1.阻塞IO模型网络

  在linux中,默认状况下全部的socket都是blocking,当用户进程调用了recvfrom这个系统调用,kernel就开始了IO的第一个阶段:准备数据。对于network io来讲,不少时候数据在一开始尚未到达(好比,尚未收到一个完整的UDP包),这个时候kernel就要等待足够的数据到来。而在用户进程这边,整个进程会被阻塞。当kernel一直等到数据准备好了,它就会将数据从kernel中拷贝到用户内存,而后kernel返回结果,用户进程才解除block的状态,从新运行起来。因此,blocking IO的特色就是在IO执行的两个阶段都被block了并发

2.非阻塞IO模型异步

  linux下,能够经过设置socket使其变为non-blocking,从图中能够看出,当用户进程发出read操做时,若是kernel中的数据尚未准备好,那么它并不会block用户进程,而是马上返回一个error。从用户进程角度讲 ,它发起一个read操做后,并不须要等待,而是立刻就获得了一个结果。用户进程判断结果是一个error时,它就知道数据尚未准备好,因而它能够再次发送read操做。一旦kernel中的数据准备好了,而且又再次收到了用户进程的system call,那么它立刻就将数据拷贝到了用户内存,而后返回。因此,用户进程实际上是须要不断的主动询问kernel数据好了没有。这种模型须要用户进程不断的查询内核,比较消耗cpu,因此应用得比较少。socket

3.IO多路复用模型async

  IO multiplexing这个词可能有点陌生,可是若是我说select,epoll,大概就都能明白了。有些地方也称这种IO方式为event driven IO。咱们都知道,select/epoll的好处就在于单个process就能够同时处理多个网络链接的IO。它的基本原理就是select/epoll这个function会不断的轮询所负责的全部socket,当某个socket有数据到达了,就通知用户进程。函数

  当用户进程调用了select,那么整个进程会被block,而同时,kernel会“监视”全部select负责的socket,当任何一个socket中的数据准备好了,select就会返回。这个时候用户进程再调用read操做,将数据从kernel拷贝到用户进程。
  这个图和blocking IO的图其实并无太大的不一样,事实上,还更差一些。由于这里须要使用两个system call (select 和 recvfrom),而blocking IO只调用了一个system call (recvfrom)。可是,用select的优点在于它能够同时处理多个connection。高并发

  在IO multiplexing Model中,实际中,对于每个socket,通常都设置成为non-blocking,可是,如上图所示,整个用户的process实际上是一直被block的。只不过process是被select这个函数block,而不是被socket IO给block。

4.信号驱动的IO模型

  

  首先经过sigaction系统调用注册信号处理函数,而后当即返回,进程继续运行,这一过程是非阻塞的。当数据准备好后,内核发送SIGIO信号给进程,进程收到该信号后,读取准备好的数据。

5.异步IO模型

  

  用户进程发起read操做以后,马上就能够开始去作其它的事。而另外一方面,从kernel的角度,当它受到一个asynchronous read以后,首先它会马上返回,因此不会对用户进程产生任何block。而后,kernel会等待数据准备完成,而后将数据拷贝到用户内存,当这一切都完成以后,kernel会给用户进程发送一个signal,告诉它read操做完成了。

关键词总结对比:

阻塞 调用进程一直被阻塞,直到操做完成。
非阻塞 在内核的数据还未准备好时,会当即返回。
同步 引发请求进程阻塞,直到IO操做完成。
异步 不会引发请求进程阻塞。所以上述五种IO模型只有第五种是异步IO模型。

  从上面表格所列的咱们对阻塞非阻塞,同步异步的理解,咱们编写的网络程序基本上不多使用异步,至少我在工程代码里不多看到有异步代码。事实上,咱们用的最多的模型应该是IO多路复用模型,且一般将其中的每个socket都设置为非阻塞。

  next.....

相关文章
相关标签/搜索