How to construct a finite state machine for a Linux Application

Source: Internet
Author: User
Finite Automation machine is an important cornerstone of computer science. It is usually called a finite state machine (Finite State Machine) in the field of software development ), it is a design pattern that is widely used ). This article describes how to build a software system based on the state machine and how to use tools in Linux to automatically generate a practical state machine framework.
  
   1. What is a state machine?
A finite state machine is a tool used to model object behavior. Its role is to describe the sequence of states that an object has experienced during its lifecycle, and how to respond to various events from outside. In an object-oriented software system, no matter how simple or complex an object is, it will inevitably go through a complete process from initial creation to final extinction, this is usually called the lifecycle of an object. Generally, an object cannot be completely isolated during its life cycle. It must affect other objects by sending messages, or change itself by accepting messages. In most cases, these messages are just simple and synchronous method calls. For example, in the bank customer management system, when an instance of the customer class is required, the getbalance () method defined in the account class may be called. In this simple case, the Class Customer does not need a finite state machine to describe its own behavior, mainly because its current behavior does not depend on a previous state.
  
Unfortunately, not all cases will be so simple. In fact, many practical software systems must maintain one or two very critical objects, which usually have very complex state conversion relationships, in addition, it is necessary to respond to various asynchronous events from external sources. For example, in a VoIP Phone System, telephone instances must be able to respond to random calls from the other party, key events from the user, and signaling from the network. When processing these messages, telephone-like behaviors depend entirely on the current status. Therefore, using a state machine is a good choice.
  
The game engine is one of the most successful applications of finite state machines. Because a well-designed state machine can be used to replace some artificial intelligence algorithms, therefore, each role or device in the game may be embedded with a state machine. Consider a simple object such as the gate in RPG games. It has four states: open, closed, locked, and unlocked, as shown in 1. When a player reaches a locked door, if he has found the key to open the door, he can use it to change the current status of the door to unlocked, you can also switch the door knob to opened to successfully enter the city.
  
Figure 1 state machine controlling the city gate
   
When describing finite state machines, States, events, transformations, and actions are common basic concepts.
  
A State is a condition in the lifecycle of an object. an object in a specific State must meet certain conditions, perform certain actions, or wait for certain events.
Events refer to things that occupy a certain position in time and space and are meaningful to the state machine. Events usually cause state changes, prompting the state machine to switch from one state to another.
Transition refers to a relationship between two States, indicating that the object will perform certain actions in the first State, the second state is entered when a specific condition is met when an event occurs.
Action refers to the atomic operations that can be performed in the state machine. The so-called Atomic operations refer to the operations that cannot be interrupted by other messages during the running process and must be executed continuously.
  
   2. Manually write a State Machine
Unlike other commonly used design patterns, when programmers want to add state machines to their software systems, they must write an additional part of the code for logical control. If the system is complex enough, this part of code is still quite difficult to implement and maintain. When implementing a finite state machine, the switch statement is the simplest and most direct method. The basic idea is to set a case Branch for each State in the state machine, it is used to control the status. The following code demonstrates how to use the switch statement to implement the state machine shown in Figure 1:
  
Switch (state ){
  
// Process the branch of opened
Case (opened ):{
// Execute the open action
Open ();
// Check for closedoor events
If (closedoor ()){
// Switch the current status to closed
Changestate (closed)
}
Break;
}
  
// Handle the branch of the closed state
Case (closed ):{
// Execute the close action
Close ();
// Check whether opendoor events exist
If (opendoor ()){
// Convert the current status to opened
Changestate (opened );
}
// Check for lockdoor events
If (lockdoor ()){
// Switch the current status to locked
Changestate (locked );
}
Break;
}
  
// Process the locked Branch
Case (locked ):{
// Execute the lock action
Lock ();
// Check for unlockdoor events
If (unlockdoor ()){
// Switch the current status to unlocked
Changestate (unlocked );
}
Break;
}
  
// Handle unlocked branches
Case (unlocked ):{
// Execute the action unlock
Unlock ();
// Check for lockdoor events
If (lockdoor ()){
// Switch the current status to locked
Changestate (locked)
}
// Check whether opendoor events exist
If (opendoor ()){
// Convert the current status to opened
Changesate (opened );
}
Break;
}
  
}
The Finite State Machine implemented by the switch statement does work well, but the code is not very readable, mainly because the conversion between States is realized, check the conversion conditions and perform state conversion in the current state. For example, when the city gate is in the opened State, you need to call the closedoor () function in the corresponding case to check whether status conversion is necessary. If yes, you also need to call changestate () the function switches the current status to closed. Obviously, if multiple different conversion conditions need to be checked in each State, and the state machine needs to switch to different States according to the check results, such code will be boring and difficult to understand. From the perspective of code refactoring, it is better to introduce the checkstatechange () and commit mstatechange () functions to check the conversion conditions, and the various actions that need to be performed to activate the conversion. In this way, the program structure will become clearer:
Switch (state ){
  
// Process the branch of opened
Case (opened ):{
// Execute the open action
Open ();
// Check whether there are events that trigger status conversion.
If (checkstatechange ()){
// Convert the state machine
Optional mstatechange ();
}
Break;
}
  
// Handle the branch of the closed state
Case (closed ):{
// Execute the close action
Close ();
// Check whether there are events that trigger status conversion.
If (checkstatechange ()){
// Convert the state machine
Optional mstatechange ();
}
Break;
}
  
// Process the locked Branch
Case (locked ):{
// Execute the lock action
Lock ();
// Check whether there are events that trigger status conversion.
If (checkstatechange ()){
// Convert the state machine
Optional mstatechange ();
}
Break;
}
  
// Handle unlocked branches
Case (unlocked ):{
// Execute the lock action
Unlock ();
// Check whether there are events that trigger status conversion.
If (checkstatechange ()){
// Convert the state machine
Optional mstatechange ();
}
Break;
}
  
}
But the checkstatechange () and performstatechange () functions will become very bloated and even difficult to implement internal logic in the face of complicated state machines.
  
For a long period of time, the use of the switch statement has always been the only way to implement a finite state machine, and most of the complex software systems such as compilers directly adopt this implementation method. However, as the state machine application deepens, the constructed state machine becomes more and more complex. This method also begins to face various severe challenges. The biggest headache is that if there are many states in the state machine, or the Transition Relationship between States is very complex. The state machine constructed by using the switch statement is not maintained.
  
   Iii. Automatic Generation of State Machine
Writing state machines for practical software systems is not very easy, especially when the state machines are complex, many programmers with similar experiences often refer to it as "uncreative" because they need to devote a lot of time and energy to how to manage various states in the state machine, rather than the running logic of the program itself. As a general software design model, the state machines of various software systems certainly have some commonalities. Therefore, people begin to develop some tools to automatically generate framework code of finite state machines, in Linux, there is a good choice -- fsme (Finite State Machine editor ).
  
Figure 2 visual fsme
   
Fsme is a Finite State Machine Tool Based on QT. It allows users to model the state machine required by the program in a graphical manner, it can also automatically generate the state machine Framework Code implemented in C ++ or Python. The following describes how to use fsme to automatically generate the state machine code required in the program by taking the state machine at the Gate 1 as an example.
  
3.1 state machine Modeling
First Run FS

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.