代码地址
文章来源地址https://www.toymoban.com/news/detail-424305.html
1.有限状态机
- 逻辑单元内部的一种高效编程方法:有限状态机
(finite state machine)
。 - 有的应用层协议头部包含数据包类型字段,每种类型可以映射为逻辑单元的一种执行状态,服务器可以根据它来编写相应的处理逻辑。如下是一种状态独立的有限状态机:
STATE_MACHINE( Package _pack )
{
PackageType _type = _pack.GetType();
switch( _type )
{
case type_A:
process_package_A( _pack );
break;
case type_B:
process_package_B( _pack );
break;
}
}
- 这是一个简单的有限状态机,只不过该状态机的每个状态都是相互独立的,即状态之间没有相互转移。状态之间的转移是需要状态机内部驱动,如下代码:
STATE_MACHINE()
{
State cur_State = type_A;
while( cur_State != type_C )
{
Package _pack = getNewPackage();
switch( cur_State )
{
case type_A:
process_package_state_A( _pack );
cur_State = type_B;
break;
case type_B:
process_package_state_B( _pack );
cur_State = type_C;
break;
}
}
}
- 该状态机包含三种状态:
type_A
、type_B
和type_C
,其中type_A
是状态机的开始状态,type_C
是状态机的结束状态。状态机的当前状态记录在cur_State
变量中。在一趟循环过程中,状态机先通过getNewPackage
方法获得一个新的数据包,然后根据cur_State
变量的值判断如何处理该数据包。数据包处理完之后,状态机通过给cur_State
变量传递目标状态值来实现状态转移。那么当状态机进入下一趟循环时,它将执行新的状态对应的逻辑。
2.EPOLLONESHOT事件
- 即使可以使用
ET
模式,一个socket
上的某个事件还是可能被触发多次。这在并发程序中就会引起一个问题。比如一个线程在读取完某个socket
上的数据后开始处理这些数据,而在数据的处理过程中该socket
上又有新数据可读(EPOLLIN
再次被触发),此时另外一个线程被唤醒来读取这些新的数据。于是就出现了两个线程同时操作一个socket
的局面。一个socket
连接在任一时刻都只被一个线程处理,可以使用epoll
的EPOLLONESHOT
事件实现。 - 对于注册了
EPOLLONESHOT
事件的文件描述符,操作系统最多触发其上注册的一个可读、可写或者异常事件,且只触发一次,除非我们使用epoll_ctl
函数重置该文件描述符上注册的EPOLLONESHOT
事件。这样,当一个线程在处理某个socket
时,其他线程是不可能有机会操作该socket
的。但反过来思考,注册了EPOLLONESHOT
事件的socket
一旦被某个线程处理完毕, 该线程就应该立即重置这个socket
上的EPOLLONESHOT
事件,以确保这个socket
下一次可读时,其EPOLLIN
事件能被触发,进而让其他工作线程有机会继续处理这个socket
文章来源:https://www.toymoban.com/news/detail-424305.html
到了这里,关于5.6和5.7、项目整体流程代码实现,解析http请求报文的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!