Process Management
Process Management
A process can be in any of the following states: NEW, READY, RUNNING, WAITING, and TERMINATED . A process is in the NEW state when it is being created. Once created, it moves to the READY state, where it waits for CPU allocation by the scheduler. When the CPU scheduler selects the process, it moves to the RUNNING state to execute . If the process needs to wait for an event like I/O completion, it transitions to the WAITING state. Once the event is completed, it returns to the READY state . Finally, the process enters the TERMINATED state when it finishes execution or is explicitly killed, marking the end of its lifecycle . State transitions occur based on system scheduling and resource availability .
A Process Control Block (PCB) is a data structure maintained by the operating system for every process . It contains all the essential information about the process such as the process state (ready, running, waiting, etc.), program counter (location of the next instruction to execute), CPU registers, memory-management information (memory allocated to the process), CPU scheduling information (like priorities and scheduling queue pointers), accounting information (CPU time used, time limits, etc.), and I/O status information (devices allocated and list of open files). This information is crucial for process management to ensure the process is executing correctly and efficiently .
In operating systems like Linux, processes are organized in a hierarchical structure known as a process tree. The init process, with PID 1, acts as the root from which all other processes descend . When a process creates a new process using the fork() system call, it becomes the parent of the newly created child process. This relationship is represented as branches in the process tree, forming a parent-child hierarchy . This structure is essential for process management as it allows the operating system to track all processes and manage resources allocation, control the execution of tasks, and handle process termination scenarios. For instance, a parent process may allocate resources to the child or terminate the child upon exit or completion of its task .
The process scheduler aims to maximize CPU utilization by ensuring that the CPU is always executing a process . In a multiprogramming environment, this might mean switching between processes frequently to give the appearance of simultaneous execution, which is crucial for time-sharing systems . There are different types of schedulers involved: the long-term scheduler (job scheduler) selects which processes should be brought into the ready queue and is invoked infrequently, so it can afford to be slower . On the other hand, the short-term scheduler (CPU scheduler) selects which of the ready processes will be executed next and needs to be fast as it is invoked frequently . Also, there is a medium-term scheduler which can be involved in swapping processes in and out of memory to balance the load between I/O and CPU-bound processes .
The fork() system call is used to create a new process in UNIX-based systems. When fork() is called, it creates a child process by duplicating the address space of the parent process . After a successful fork() call, two processes are created: the parent and the child process. The distinction between these two processes can be made by checking the return value of fork(). The parent process receives the child's PID (a positive value), while the child process receives a return value of zero . If fork() fails, it returns a negative value to indicate an error in the creation of the child process .
A process is an independent program in execution, which includes a set of resources like memory, I/O devices, etc. It has separate address spaces divided into sections such as stack, heap, text, and data . Each process has its own Process Control Block (PCB), which contains information like the process state, program counter, and memory-management information . A thread, on the other hand, is the smallest unit of execution within a process. It operates within the process's memory space and shares resources like code, data, and files with other threads within the same process, but has its own stack, register set, and program counter . Threads are more efficient in terms of execution as context switching between threads of the same process requires saving and loading hardware contexts but typically consumes less overhead than switching between processes .
Context switching refers to the process where the CPU switches from executing one process to another. It involves saving the state of the currently running process in its PCB and loading the state of the next process to execute . Context switching is considered an overhead because the CPU does not perform any useful work during this time; it only transitions between processes. The time taken for a context switch can significantly affect system performance, as it depends on factors like memory speed and the number of registers that need to be saved . While context switching is necessary for multitasking, frequent switching can decrease CPU efficiency and responsiveness, especially in systems with high process loads .
Zombie processes occur when child processes have completed execution but still reside in the process table due to the parent not calling wait() to read their exit status. They consume minimal resources but can fill the process table, preventing new processes from being started if the table gets full . Orphan processes, however, are processes whose parent has terminated. These are adopted by the init process in Unix-based systems and persist until they complete execution. While orphans are generally not problematic, having many orphans could indicate poor process management, potentially leading to improper resource utilization . Proper handling and cleanup of these processes are important for maintaining system stability and efficiency .
The fork() system call is used to create a copy of the existing process, resulting in two processes: the original (parent) and the newly created one (child) with identical code, data, and heap memory segments . It provides a mechanism for a process to create a new one. In contrast, the exec() family of system calls is used to replace the current process's memory space with a new program. After a fork(), a process can call exec() to run a different program, whereas fork() only duplicates the existing process without altering the current program . The combination of fork() and exec() is fundamental to Unix process management, allowing for flexibility in starting new programs with separate execution paths .
Short-term and long-term schedulers perform distinct roles in process management in operating systems. The short-term scheduler, also known as the CPU scheduler, is responsible for selecting which ready process should execute next and is invoked very frequently as processes need to be rotated in and out of the CPU regularly, which demands low-latency, high-speed decision-making . It’s crucial for maintaining performance and responsiveness in time-sharing systems. Conversely, the long-term scheduler, or job scheduler, determines which jobs or processes should enter the system for processing and is invoked infrequently (e.g., every few seconds or minutes). It balances the mix of CPU-bound and I/O-bound processes, aiming for optimal CPU utilization . This strategic overview helps maintain system stability and load balancing over longer periods.