winston 发表于 2012-2-29 15:02:52

IOCP浅析

作者:eliteYang
这一年半来一直在做游戏项目逻辑层,学会了不少东西,觉得自己应该看看服务器底层的东西了,主要的东西就是网络模块,网络模块是沿用以前项目的,在 我们项目中被我们头改动过几次,现在还是比较稳定的。因为是Windows平台,所以用的依然是被大多数人神话了的IOCP,不过的确IOCP 表现的非常不错。
什么是IOCP?众所周知,为了绝对同步,所以很多模式都采用的是同步模式,而不是异步,这样就会产生很大情况下在等待,CPU在切换时间片,从而导致效率比较低。自从MS在winsocket2中引入了IOCP这个模型之后,他才开始被大家所认知。
IOCP (I/O Completion Port),中文译作IO完成端口,他是一个异步I/O操作的API,他可以高效的将I/O事件通知给我们的应用程序,那游戏项目来说,就是客户端或者服务器。
他与Socket基础APIselect()或其他异步方法不同的是,他需要讲一个Socket和一个完成端口绑定在一起,然后就可以进行网路通信了。
什么是同步/异步?所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回。按照这个定义,其实绝大多数函数都是同步调用(例如sin, isdigit等)。
异步的概念和同步相对。当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。
逻辑上通俗来讲是完成一件事再去做另外一件事情就是同步,而一起做两件或者两件以上的事情就是异步了。类似于Win32API中的SendMessage()和PostMessage(),你可以将他理解成单线程和多线程的区别。
拿游戏服务器与客户端通信来说:
如果是同步:
ClientA发送一条Msg1Req消息给Server,这个时候ClientA就会等待Server处理Msg1Req。这段时间内ClientA只有等待,因为Server还没有给ClientA回复Msg1Ack消息,所以ClientA只能痴痴的等,等到回复之后,才能处理第二条Msg2Req消息,这样无疑就会大大的降低性能,产生非常差的用户体验。
如果是异步:
ClientA发送一条Msg1Req消息给Server,ClientA有发送第二条Msg2Req消息给Server,Server会将他们都存入队列,一条一条处理,处理完之后回复给ClientA,这样用户就可以不必等待,效率就会非常高。
什么是阻塞/非阻塞?阻塞调用是指调用结果返回之前,当前线程会被挂起。函数只有在得到结果之后才会返回。可能阻塞和同步有点类似,但是同步调用的时候线程还是激活的,而阻塞时线程会被挂起。
非阻塞调用和阻塞的概念相对应,指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回。
对象的阻塞模式和阻塞函数调用对象是否处于阻塞模式和函数是不是阻塞调用有很强的相关性,但是并不是一一对应的。阻塞对象上可以有非阻塞的调用方 式,我们可以通过一定的API去轮询状态,在适当的时候调用阻塞函数,就可以避免阻塞。而对于非阻塞对象,调用特殊的函数也可以进入阻塞调用。函数 select就是这样的一个例子。
对IOCP的评价如何?I/O完成端口可能是Win32提供的最复杂的内核对象。 Jeffrey Richter
这是实现高容量网络服务器的最佳方法。Microsoft Corporation
完成端口模型提供了最好的伸缩性。这个模型非常适用来处理数百乃至上千个套接字。Anthony Jones & Jim Ohlund
I/O completion ports特别显得重要,因为它们是唯一适用于高负载服务器[必须同时维护许多连接线路的一个技术。Completion ports利用一些线程,帮助平衡由I/O请求所引起的负载。这样的架构特别适合用在SMP系统中产生的”scalable”服务器。 Jim Beveridge & Robert Wiener
IOCP中的完成是指什么意思?网络通信说白了就是将一堆数据发过来发过去,到底还是数据的操作。不过大家都知道I/O操作是非常慢的,包括打印机、调制解调器、硬盘等,至少相对于CPU来说是非常慢的。坐等I/O是很浪费时间的事情,可能你只需要读取100KB的数据,假设读了0.1秒,假设CPU是3.0G Hz,那么CPU已经运行了0.3G次了,所以CPU这个时候就不满意了,哥这么NB,为什么要等你?
所以我们用另外一个线程来处理I/O操作,使用重叠IO(Overlapped I/O)技术,应用程序可以要求OS为其传输数据,在完成的时候通知应用程序,然后在进行相应操作,这也就是为什么叫完成的原因。这可以使得应用程序在I/O传输期间可以做其他事情,这也可以最大限度的利用线程,而让最NB的CPU不至于痴痴等待。
下来会将IOCP和网络有什么关系,以及IOCP的简单应用。
   
本文固定链接: http://www.cppfans.org/1054.html | C++爱好者博客™

页: [1]
查看完整版本: IOCP浅析