Content Introduction and History File I/O The File System Shell Programming Standard Unix Files and Configuration Processes
Programs are instruction sets stored on a permanent medium (e.g. harddisc). Processes are instantiated programs which run in a computer s main memory. Modern operating systems can executed several processes at the same time. By switching quickly between the processes, the OS creates the illusion of parallel process execution. Process switching is done by the so-called scheduler. Process can be in different states: Waiting for input Computing Process activated by scheduler Scheduler chooses different process Blocked Input available Ready
State Computing: Process is currently using the processor. State Ready: Scheduler has suspended the process. The process is waiting to be activated by the scheduler. State Blocked: The process needs some input which is currently not available. To avoid busy waiting the process is deactivated. Waiting for input Computing Process activated by scheduler Scheduler chooses different process Blocked Input available Ready
Waiting for input Computing Process activated by scheduler Scheduler chooses different process Blocked Input available Ready To reactivate a process its previous state must be restored. This includes: the program counter all registers status word stack pointer memory pointers
Process activation and suspension: Registers PC, SC, of Process1 are saved Registers, PC, SC, of Process 2 are restored Process 1 Process 2 The scheduler decides which process is when activated and deactivated. This is the socalled scheduling strategy. time
Each process is described by one so-called Process Control Block (PCB): Dynamic Infos Memory Management File Management Etc. Registers Pointer to Textseg. Root Direc. Priority Programm Counter Pointer to Dataseg. Working Direc. Process ID Program Status Word Pointer to Stackseg. File Descriptor Scheduling Infos Stack Pointer User-ID Parent Process Process State Group-ID Signals Starting Time Next Alarm
src/proc.h: struct proc { struct stackframe_s p_reg; /* process' registers saved in stack frame */ proc_nr_t p_nr; /* number of this process (for fast access) */ struct priv *p_priv; /* system privileges structure */ char p_rts_flags; /* SENDING, RECEIVING, etc. */ char p_misc_flags; /* Flags that do suspend the process */ char p_priority; /* current scheduling priority */ char p_max_priority; /* maximum scheduling priority */ char p_ticks_left; /* number of scheduling ticks left */ char p_quantum_size; /* quantum size in ticks */ struct mem_map p_memmap[nr_local_segs]; /* memory map (T, D, S) */ clock_t p_user_time; /* user time in ticks */ clock_t p_sys_time; /* sys time in ticks */
Unix: 1.fork() creates a copy of the running process 2.loading of new memory image (program), e.g. by calling execve() Windows: 1. CreateProcess() creates new process and loads new program
Unix processes remember their parent process. Since all Unix operating systems first create an initial process named init, every Unix system is essentially a tree of processes with init being the root. init forks off one process for each terminal. Users can log in into each terminal. The shell process than forks off new shells for each command. Windows process are not hierarchically.
Process can end in different ways: self termination termination by means of a serious problem termination by operating system self termination: Unix: call of exit() Windows: call of exitprocess() termination by means of a serious problem: invalid instruction invalid memory address division by zero termination by operating system: Unix: kill() Windows: TerminateProcess()
As mentioned, processes take care of resource and execution control. Sometimes closely related program modules should run in parallel, communicate with each other and use the same resources. So while execution control is needed, resource control is unnecessary and might even hinder the communication, e.g. by preventing shared memory. For such cases, threads were invented. Threads are therefore light-weighted processes which only need some execution information: Dynamic Infos Memory Management File Management Etc. Registers Pointer to Textseg. Root Direc. Priority Programm Counter Pointer to Dataseg. Working Direc. Process ID Program Status Word Pointer to Stackseg. File Descriptor Scheduling Infos Stack Pointer User-ID Parent Process Process State Group-ID Signals Starting Time Next Alarm
A process is instantiated from a program file. When a program is instantiated, first of all a startup code is executed which then jumps into the main function. The program layout is as follows: Command line arguments and env. variables Stack Heap uninitialized data (bss) set to zero by exec Shared libraries are a way for processes to share code. initialized data Text copied from program
Dynamic memory allocation happens on the heap using the functions malloc, calloc, and realloc. free is used to free the memory. Assignment: 1) Write a C program which allocates some memory, uses it to store a string, and frees the memory again.
Creation of a new process Process ID = 41. id = fork(); id == 42. Process ID = 42. id = fork(); id == 0. The child process is a copy of the parent process, i.e. data, bss, and heap, stack segments are copied. Both share the same text segment. #include <unistd.h> All user ID/Group ID, terminals, directories, etc. are also copied. pid_t fork(void); Parent process: Process ID of child process. Child process: 0
#include <unistd.h> pid_t getpid(void); pid_t getppid(void); // Returns process ID // Returns parent s process ID #include <stdlib.h> void exit(int statue); void abort(void); // Finishes process // Aborts a process #include <sys/wait.h> pid_t wait(int *statloc); // Waits for a child process // to finish, returns child process ID pid_t waitpid(pid_t pid, int *statloc, int options); // pid>0: Waits for the child process pid to finish, // pid==0: Waits for a child process with the same group // process ID to finish, // pid<-1: Wait for a child process with the group process ID // pid to finish
After the fork(), the child process usually changes its program image: #include <unistd.h> extern char **environ; int execl(const char *path, const char *arg0,... /*, (char *)0 */); int execle(const char *path, const char *arg0,... /*, (char *)0, char *const envp[] */); int execlp(const char *file, const char *arg0,... /*, (char *)0 */); int execv(const char *path, char *const argv[]); int execvp(const char *file, char *const argv[]); int execvp(const char *file, const char *search_path, char *const argv[]);