您的位置:首页 > 理论基础 > 计算机网络

网络编程中遇到的一些概念总结

2011-03-02 11:13 253 查看
同步、异步、阻塞、非阻塞
select模式
重叠I/O(Overlapped I/O)
完成例成(completion routines)
IOCP完成端口 (I/O Completion Port)


同步、异步、阻塞、非阻塞是IO的基本原理。同步和异步是针对功能的执行顺序来说的,而阻塞和非阻塞是针对等待IO数据的方式说的。因此这是两对概念,同步与阻塞,异步与非阻塞都没有必然的联系。通俗的说,同步就是工作线程在处理IO时等待IO完成再继续后面的工作;异步就是工作线程不等待IO处理的结果就继续后面的工作,而IO处理结果将通过回调方式返回;阻塞是在等待IO时,如果IO没有可用数据或数据没有传送完成,那么一直等待下去,直到IO处理完数据再返回;非阻塞就是不管IO是否有可用数据或数据已经传送,照样返回。只要把同步和阻塞分清,这四个概念就很容易理清了。

同步、异步、阻塞、非阻塞等原理确定了网络通信的基本网络通信模型结构。它们处理的怎么等待数据和怎么收发数据的问题,但是对通信性能并没有提供更多的指导。特别是服务端,当成千上万的连接发生并发时,降低cpu的占用率,减少内存使用率,减少带宽就成为了很关键的问题。因此便有先有了重叠I/O(Overlapped I/O)。

重叠I/O(Overlapped I/O)是怎么一回事呢?


如果应用程序投递了一个10KB大小的缓冲区来接收数据,且数据已经到达套接字,则该数据将直接被拷贝到投递的缓冲区。而阻塞、select、WSAAsyncSelect以及WSAEventSelect等4种模型种,数据到达并拷贝到单套接字接收缓冲区中,此时应用程序会被告知可以读入的容量。当应用程序调用接收函数之后,数据才从单套接字缓冲区拷贝到应用程序的缓冲区,差别就体现出来了。我想之所以叫重叠也就是因为它是两个缓冲重叠的意思。就这么一重叠就剩了不少空间和不少事情。

提重叠I/O(Overlapped I/O)之前应该先提select模式,因为它是最接近同步、异步、阻塞、非阻塞模式的一种模式。select模式、WSAAsyncSelect以及 WSAEventSelect都是通过轮询socket列表来确定那个socket是当前有效的(它们的原理还是有点不一样的)。好处是防止在在阻塞模式的套接字里被锁死,避免在非阻塞套接字里重复检查WSAEWOULDBLOCK错误。
也就是说,select模式提供了一种比较优秀的查询方式来判断当前连接的状态,避免了直接使用阻塞或者非阻塞所导致的问题。

提重叠I/O(Overlapped I/O)提供了比select模式更优秀的缓冲管理,那它是不是也提供了比select更优秀的轮询方式呢?可以说是,也可以说不是。因为提重叠I /O(Overlapped I/O)并没有直接提供这样的方法,而是提供了一种手段。这手段是在Overlapped数据结构里标记了该数据所属的socket和有数据到的来。怎么捕获这个事件?那就是完成例成(completion routines)和事件对象通知(event object notification) 所干的事情了。完成例成(completion routines)类似于dotnet里面的异步,在socket接收数据时给WSARecv传送一个完成后回调的函数句柄,来达到捕获数据到来的事件;至于事件对象通知(event object notification) 利用的是Overlapped数据结构里包含“有数据到来的事件”的WSAEVENT hEvent成员与事件句柄关联实现的,这个就象是使用了类为外部提供事件通知的方式。

使用事件或者是回调都要比轮询高效。因此重叠I/O(Overlapped I/O)可以支持很高的连接数,传说可以上万。但是重叠I/O(Overlapped I/O)也有不足的地方。重叠缓冲是很好的做法,但是对应每个socket都要有一个缓冲,那么一万个连接就会有一万个缓冲了。另外还有就是无论是异步还是事件来唤醒线程,都和缓冲存在一个连接一个线程的情况。不面对大量的并发,这两个问题并不明显,但是如果并发连接数量达到某个级别,cpu和内存都将存在严重的浪费。而且其支持的连接数与硬件性能的比只能是一个固定值。

为了解决重叠I/O的问题,便有了IOCP完成端口 (I/O Completion Port)。为了解决大量并发产生的资源浪费,完成端口引入了类似线程池和资源自动分配回收的两种技术(这里之所以说是类似,是因为对于IOCP的原理还没有作更深入的研究说不准其准确的原理,只能通过它的现象来认为那是线程池+高效调度+资源回收综合起来的)。所谓的大量并发连接不是指同一时间内的连接数量,而是在某时间区间内的连接数量。因此在该时间区间内并不是所有的连接线程都是活动的,只要具有高效的线程分配和调度,那么在每个时刻提供比整个区间内连接线程小得多的活动线程也能把该时间区间内的并发处理,这就是线程池的好处。对于大量的并发短连接,其缓冲绝对是可重复使用的,其线程也是可重复使用的,因此准确高效的资源回收能是资源最大效率的运用起来。通过对线程和缓冲的有效再利用使完成端口在更小的资源环境下取得比重叠I/O更好的性能。

完成端口这个名字使不少人迷惑,我们完全可以通过它的原理和应用来理解这个名字。完成端口是通过调度线程和提供资源重用来取得高效的,因此完成端口把连接的调度和其缓冲的分配都进行了封装,提供了很容易使用的接口。我想完成端口的“完成”便是这样而来--调度和资源分配的自动完成,“端口”--就是指IO端口,每个IO设备都有其自己的IO号,这个IO号又被成为IO的端口。那英文名里面的I/O又是什么回事呢?这和重叠I/O是一样的,就是指它们是应用在I/O上的一种技术。广义的说,网络不也是IO?

重叠I/O和IOCP完成端口确实是可以用在所有的IO应用上。而完成端口因为封装了调度和回收机制,还可以把它当作高效的队列处理技术和线程调度技术来使用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: