事件模型、状态机在高性能网络IO中应用

高性能网络IO有2个鲜明特征:

1、没有等待。当然这个特征必须做个界定,即任何在网络发生数据传输请求的时候,都能够马上满足。

2、没有内存拷贝。由于网络IO的数据量十分庞大,所以任何内存拷贝的存在将导致很大的性能损失。

 

在已知的 IO模型中,都必须存在这2个特征。我们以EPOLL为例,性能最高的是边缘触发模式。只有当缓冲区中存在数据时,应用层才会被通知。而对于内核来说,通 知的时候,本身只高知应用层,数据已经能够提供,但却没有告知数据的具体内容,因此,并没有内存拷贝行为。但是,由于内核和应用层之间,不存在数据共享的 途径,因此将数据从内核中,拷贝到应用层内存中,是必须存在的行为。

 

    事件模型是利用EPOLL等高性能网络IO模型的最好方式,实际上他将消灭等待的时机延迟到最靠近最终使用数据的层次,从而降低了内存拷贝的可能性。但 是,我们也要看到,事件模型是无序的,也就是说,我们在事件模型中不能限定事件发生的顺序。打个比方,一个登录过程分为几个步骤:

     1、C-->发送登录请求 --> S

     2、S-->登录应答 -->C

     3、C-->发送名称、密码 -->S

     4、S-->验证结果-->C

 

这是一个很简单的过程,如果是阻塞模式的话,我们很简单的用几个过程:

    1、send(登录请求)

    2、recv(登录应答)

    3、send(用户、密码)

    4、recv(验证结果)

每次recv的时候,我们很显然是知道他一定会返回什么,比如recv(登录应答),如果不是,那么直接报告登录错误,然后退出。

 

可是事件模式中却不是这样。当你接收到一个登录应答时,就能确定要发送用户和密码吗?否!!!!因为你不知道是否已经发送过登录请求。也许有人会说,我没发登录请求,对方返回登录应答做什么呢?也许是对方的错误,但不管如何,你不能保证。

 

 

    于是,状态机就被引入到这种事件模型中,来保证具备上下文关系协议中,如何正确运行。当我成功发送登录请求时,本地状态机被置为 LOGIN_REQUEST_SENT,只能当我接收到登录应答时,状态被重新置为LOGIN_USER_PWD_SENT。如此这般,就能保证这个过程 在事件模型被正确执行。

 

    事件模型在某种情况下,却能完全摒弃状态机,比如HTTP服务器中。每个HTTP请求都会携带完整的信息,因此,没有必要考虑状态和上下文关系。

 

 

    还有一种比较复杂的情况,却需要复杂的状态机,比如telnet协议。这个协议的状态变化很复杂,事件模型很难处理。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值