Skip to content

Processes Overview

  • A process is an abstract entity, defined by the kernel, to which system resources are allocated in order to execute a program.
  • From the kernel’s point of view, a process consists of user-space memory containing program code and variables used by that code, and a range of kernel data structures that maintain information about the state of the process:
    • PID
    • Virtual memory tables
    • File descriptors tables
    • Information relating to signal delivery and handling
    • Process resource usages and limits
    • Current working directory
    • Others …

Process ID and Parent Process ID

  • Each process has a process ID (PID), a positive unique integer that identifies the process on the system.
#include <unistd.h>
pid_t getpid(void);
// Always successfully returns process ID of caller
// typedef int pid_t;
  • Each process has a parent, to find out the process ID of its parent, use the getppid() system call
#include <unistd.h>
pid_t getppid(void);
// Always successfully returns process ID of parent of caller
  • Note that the parent of each process has its own parent, and so on, going all the way back to process 1 (init).
  • If a child process becomes orphaned because its “birth” parent terminates, then the child is adopted by the init process.

Virtual memory layout of a process

Virtual memory management

Basic terms

  • A virtual memory scheme splits the memory used by each program into small, fixed-size units called pages.

  • Correspondingly, RAM is divided into a series of page frames of the same size.

  • At any one time, only some of the pages of a program need to be resident in physical memory page frames; these pages form the so-called resident set.

  • Copies of the unused pages of a program are maintained in the swap area — a reserved area of disk space used to supplement the computer’s RAM—and loaded into physical memory only as required.

  • When a process references a page that is not currently resident in physical memory, a page fault occurs, at which point the kernel suspends execution of the process while the page is loaded from disk into memory.

  • The kernel maintains a page table for each process, as shown below: alt text

    • The page table describes the location of each page in the process’s virtual address space.
    • Each entry in the page table either indicates the location of a virtual page in RAM or indicates that it currently resides on disk.
    • Not all address ranges in the process’s VAS require page-table entries (if no entry found, return a SIGSEGV signal)

Locality of reference

  • Like most modern kernels, Linux employs a technique known as virtual memory management. The aim of this technique is to make efficient use of both the CPU and RAM (physical memory) by exploiting a property that is typical of most programs: locality of reference

  • 2 kinds of locality:

    • Spatial locality: the tendency of a program to reference memory addresses that are near those that were recently accessed.
    • Temporal locality: the tendency of a program to access the same memory addresses in the near future that it accessed in the recent past (because of loops)
  • The upshot of locality of reference is that it is possible to execute a program while maintaining only part of its address space in RAM.

  • To support this organization

Environment List

  • Each process will maintain a list of environment variables (cat /etc/$PID/environ).
  • When a new process is created, it inherits a copy of its parent’s environment.
  • A common use is in the shell.
  • To access the environment from a program, use the global variable char **environ, as shown below:
#include <stdio.h>
#include <stdlib.h>
extern char **environ;
int main(int argc, char *argv[]) {
char **p = environ;
while (*p != NULL) {
printf("%s\n", *p++);
}
exit(EXIT_SUCCESS);
}

Retrieve retrieves individual values from the process environment.

#include <stdlib.h>
char *getenv(const char *name);
// Returns pointer to (value) string, or NULL if no such variable
#include <stdlib.h>
int putenv(char *string);
// Returns 0 on success, or nonzero on error
int setenv(const char *name, const char *value, int overwrite);
// Returns 0 on success, or –1 on error
int unsetenv(const char *name);
Returns 0 on success, or –1 on error
  • Clean an entire environment
#define _BSD_SOURCE /* Or: #define _SVID_SOURCE */
#include <stdlib.h>
int clearenv(void)
// Returns 0 on success, or a nonzero on error