Basics
Last updated
Was this helpful?
Last updated
Was this helpful?
A process is essentially a program in execution (in memory), and the status and activity of a process is represented by the contents of the processor's registers (i.e., PC, SP, IP, and general purpose registers).
The memory layout of a process typically includes the following sections:
Text Section: where executable code is stored [read-only].
Data Section: global and initialized (assigned non-zero values) (static) global and local variables [read-write].
Heap Section: memory dynamically allocated and used during run time [read-write].
Stack Section: temporary storage for invoking functions; this section stores function parameters, return addresses, and local variables (defined within function scope).
Text and Data sections are static in size, while heap and stack can grow and shrink. When a function is called, an activation record is pushed onto the stack. The activation record includes function parameters, local variables, and return address. When control is returned, the record is popped from the stack.
Some processes use additional memory sections. In the image above, process memory includes a section called bss, or Block Starting Symbol, which contains static uninitialized variables. Another section (not shown in the image) is the rodata section--this is the read-only data section.
The Stack and heap grow toward one another; however, the OS ensures they do not overlap.
A program, by itself, is passive and is not a process. However, a process is an active entity, and has a state along with associated resources. A program becomes a process when the executable is loaded into memory.
Considering the memory sections of a process, what's the significance of if two or more processes are associated with the same program? Although each process has the same text section, the execution path will be different; the data, heap, and stack sections will vary.
In the code snippet above, the global variable x is uninitialized and will be stored in the uninitialized data section, or BSS for ELF binaries. the global variable y is initialized to 15, thus it will be in the data section. The local integer pointer and integer variables values and i, respectively, will be stored on the stack. The dynamically allocated memory assigned to the values variable, will be heap space.
Notice that the integer pointer and integer variables values and i, respectively, are placed on the stack and not stored in the BSS section. This is because they are not static local variables. In C, a static variable means that it will be available for the duration of program execution, from beginning to end. Normal (non-static) variables are only available when the program is within scope--the function in which they are defined has been called and has control. Only static variables go in the initialized and uninitialized sections, data and bss on ELF, respectively. Even if variable values or i were initialized, neither would go in the data section because they are not static.
Remember that the OS ensures heap and stack memory spaces, which grow and shrink, don't overlap. In languages like C, it is important for a programmer to properly managing dynamically allocated memory by freeing dynamically allocated memory and setting pointers to NULL. This is necessary to avoid memory leaks and dangling pointers.
RTOS systems require determinism, which malloc() typically doesn't provide.
While process state names vary by OS, the following state names define the general states represented by processes on any OS:
New
Running
Waiting
Ready
Terminated
Some Operating systems more finely delineate process states. Only one process can be in a running state on any processor core at any instant; multicore processors can have N processes in a running state, where N represents the number of cores per processor.
Processes are represented in the OS by a process control block (sometimes called task control block), that includes the following information:
Process State: One of the states listed above (e.g., New)
Program Counter: Indicates address of the next instruction to be executed
CPU Registers: GP registers, stack and index pointer, accumulators, condition-code registers
CPU-Scheduling Information: Process priority, pointers to scheduling queues, etc.
Memory-Management Information: May include value of base and limit registers and page tables, segment tables, etc.
Accounting Information: CPU and real time used, process numbers, etc.
I/O status: List of I/O devices allocated to the process, list of open files, etc.
A thread is a process structure that is an execution location. A single thread of control allows a process to perform one task at a time, while multiple threads allow the process to perform a task per thread.
On multicore architectures, multiple threads can run in parallel. Systems that support threading, expand the PCB to include information about the threads.