A program is a passive entity stored on a secondary memory like a hard disk. When a program is executed, it is converted into an active instance that can be run by the CPU of a computer system.
To understand how a program gets converted into a process in an operating system, we need to delve into several key stages involved in this transformation. Each stage ensures that the program executes accurately and efficiently.
1. Program Creation
Source code is essential because it serves as the foundational blueprint for any software application, which is a set of human-readable instructions written in a programming language (e.g., Python, C++, Java). This code defines the logic and functionality of the software.
2. Compilation
The source code is processed by a compiler, which translates the high-level instructions into low-level machine code or object code. This step is crucial because computers can only execute machine code but this code generated is not executable.
3. Linking
After compilation, the linker combines one or more object files into a single executable file. This process resolves references between different object files, ensuring that function calls and variable references are correctly linked.
Types of Linking:
- Static Linking: All necessary libraries are combined into the executable at compile time.
- Dynamic Linking: Libraries are linked at runtime, allowing for smaller executable sizes and easier updates.
4. Loading
The loader is responsible for loading the executable file into memory. It allocates memory for the process and sets up the execution environment.
Memory Layout:
- Text Segment: The text segment, also known as the code segment, contains the compiled machine code of the program. This is the section where the executable instructions reside.
- Initialized Data Segment: This segment, often referred to simply as the data segment, contains all global and static variables that are initialized by the programmer at the time of declaration.
- Uninitialized Data Segment: The uninitialized data segment contains all global and static variables that are declared but not initialized.
- Heap: The heap is a memory segment used for dynamic memory allocation. It allows programs to request and release memory at runtime.
- Stack: The stack segment is used for static memory allocation, which includes local variables and function call management.
5. Process Creation
- When a user executes the program, the operating system creates a new process by duplicating the shell process using the
fork()
system call. This results in a child process. - The child process then calls one of the
exec()
functions to replace its memory space with the program’s executable code. This effectively transforms the child process into the program that is to be executed.
6. Process Execution
- The operating system schedules the new process for execution. The CPU fetches and executes the program instructions sequentially.
- The OS manages multiple processes by context-switching between them, ensuring that each process gets CPU time.
7. Process Termination
- When the program finishes executing, the process terminates. The operating system reclaims any resources allocated to the process, including memory and file descriptors.
- The process may return an exit status to the parent process (the shell), indicating whether it was completed successfully or encountered an error.