OS - Process
- User mode: the application does not have full access to hardware resources, e.g. a process can’t issue I/O requests, that will raise an exception, then OS would kill the process.
- Kernel mode: the OS has access to the full resources of the machine.
Allow the kernel to carefully expose certain key pieces of functionality to user programs, such as accessing the file system, creating and destroying processes, communicating with other processes, and allocating more memory.
Early Unix systems exposed around twenty calls, Linux and OpenBSD each have over 300 different calls, NetBSD has close to 500, FreeBSD has over 500.
A system call is a C procedure call, the change of mode is achieved by special instructions hidden inside:
trapinstruction: enter kernel mode
return-from-trapinstruction: back to user program in user mode
- to enter kernel-space from user-space.
- produced by software
- The defined software interrupt on x86 is interrupt number
trapis a kind of software interrupt.
- produced by hardware.
- e.g. timer(irq=0), keyboard(irq=1), etc.
- Process Control Block (PCB): a fancy way of talking about a C structure that contains information about each process
- exception: Exceptions are produced by the processor while executing instructions either in response to a programming error (for example, divide by zero) or abnormal conditions that must be handled by the kernel (for example, a page fault).
Each thread has its own private set of registers it uses for computation; thus, if there are two threads that are running on a single processor, when switching from running one (T1) to running the other (T2), a context switch must take place.
- Thread: separate registers; shared memory, opened files
- Process: separate address space, opened files
- Single-threaded Process: only one stack, one heap
- Multi-threaded Process: multiple stacks, one heap
- handing control over to the operating system kernel
- Context switch between processes: save memory(address space) state to process control block (PCB)
- Context switch between threads: save register stats to thread control blocks (TCBs), the address space remains the same
- Green Thread: scheduled by a runtime library or virtual machine (VM), emulating multithreaded environments without relying on any native OS capabilities; managed in user space instead of kernel space, enabling them to work in environments that do not have native thread support.
- Native Thread: native thread supported by the underlying operating system
- fork(): create a new process from current one with new pid, memory space, registers
- exec(): t loads code (and static data) from that executable and overwrites its current code segment (and current static data) with it; the heap and stack and other parts of the memory space of the program are re-initialized. (no new process created)
Reason for the separation of fork() and exec(): it lets the shell run code after the call to fork() but before the call to exec(); this code can alter the environment of the about-to-be-run program, and thus enables a variety of interesting features to be readily built.
exec has 6 functions：
#include <unistd.h> int execl(const char *path, const char *arg, ...); int execlp(const char *file, const char *arg, ...); int execle(const char *path, const char *arg, ..., char *const envp); int execv(const char *path, char *const argv); int execvp(const char *file, char *const argv); int execve(const char *path, char *const argv, char *const envp);
- the 3
char *argvfor arguments,
execl*functions need to list out all args and use NULL at the end.
envpto replace default environment params, others use default
execvpdo not need full path, they will try to find the file from
PATHenvironment param, others need the full path.
execveis the real sys call, others are built on top of it.
If CPU is running some user program, it cannot run OS, thus OS cannot switch processes
- Cooperative: Processes that run for too long are assumed to periodically give up the CPU so that the OS can decide to run some other task (
yieldsystem call, or other system calls)
- Non-cooperative: timer interrupt, "A timer device can be programmed to raise an interrupt every so many milliseconds; when the interrupt is raised, the currently running process is halted, and a pre-configured interrupt handler in the OS runs. At this point, the OS has regained control of the CPU, and thus can do what it pleases: stop the current process, and start a different one."