The life cycle (or execution cycle) refers to the different stages that a program goes through from its start to its completion. This entire process is what we call the program’s execution cycle.
The life cycle can be very simple, as in a console application,
In this case, when we launch a program it:
- Will start
- Will do things for a while
- Will close
But it can become much more complex, as in the case of a mobile device application or a game running on a game engine.
For example, the life cycle of an Android application looks like this.
As we can see, it is no longer as simple as start, execute, and close. There are various ways to terminate a program, and it can even be suspended and reactivated later.
The Role of the Operating System
During the life cycle of a program, the operating system (OS) plays a fundamental role at each stage, (and when I say OS we should think “whatever we are using to run our program”).
In the simplest machines (like an Arduino) the “OS” is simply a bootloader that launches the program we have executed. Other more complex machines use lightweight operating systems like FreeRTOS.
If we talk about computers or mobiles, we will have OSs like Windows, or Linux, or Android, (or whatever it is). Even if we are running a game engine, this will be an additional layer of software between our program and the hardware.
In any case, our program will run “on top” of several layers of software (the topic is quite complex and we won’t go into more details today).
But it is important for you to know when the execution life of your program starts, how it executes, and when it ends.
Entry Point
The life cycle of an application begins at the entry point, which is the starting point for the execution of the program.
At this stage, the OS is responsible for loading the program into memory and allocating the necessary resources for its execution. The OS also sets up the execution environment and provides the command-line arguments passed to the program (like input parameters).
In many programming languages, such as C++ or Java, the entry point is usually a function or method with a specific name, which indicates where the code should start executing.
For example, if we take an example in C++, we see that it has a main()
method as the entry point.
#include <iostream>
int main() {
// here is the code that will execute at the beginning
}
This would be very similar in C# or Java, for example. In these languages, the entry point for the program is indicated with the main()
method.
It is usually possible to change the name of the entry point in the project settings, or as options when compiling.
In the case of interpreted (or semi-interpreted) languages, in addition to the OS, we have an additional layer of software which is the language interpreter. Therefore, usually, in interpreted languages, the entry point to the program is simply the first line of it.
For example, in JavaScript it is enough to do,
console.log("Hello, world!");
No further indications are necessary because the interpreter is ready to execute the code just as it arrives.
Code Execution
Once the program has been loaded into memory and the execution environment has been established, we proceed to the actual execution of the code. The program follows the instructions and performs the operations defined in the source code.
During this stage, the OS is responsible for managing the execution time, allocating additional resources as needed, and ensuring a secure and protected execution environment.
The OS also provides access to various system functionalities and services, such as communication with input/output devices, file management, and interaction with other running programs. Additionally, it monitors the program for possible errors or abnormal behaviors that may affect system stability.
Finally, in the case of interpreted languages, we also have the interpreter performing its tasks, which usually include memory management or input and output.
Exit Code
At some point, the program will stop executing. This can either be because the machine running it is turned off or restarted, or because the program completes (we will skip the part about turning off the machine, because it is not a controlled “termination” of a program).
When a program finishes, it informs the OS that it has no more pending tasks to perform and that it has completed its function. To do so, it produces an exit code that indicates the state in which the program finished.
The exit code is returned to the OS and can be used by other programs or scripts to make decisions or perform actions based on the execution result.
The exit code generally has an integer value, where a value of 0 indicates that the program ran successfully without errors. Other non-zero values may indicate different types of errors or exceptional conditions, and their interpretation may vary depending on the program and the operating system.
After the program finishes, with the exit code, the OS can take appropriate actions (for example, freeing the memory it had reserved for the process, or logging if an error occurred during execution).
In interpreted languages, generally, the OS is not informed that the program has finished. Because, indeed, the OS is running the interpreter, not the program. So, the termination management of the process is handled by the interpreter itself, but it continues running.