Process Process Concept • Process – a program in execution • Textbook uses the terms job and process almost interchangeably • A process includes: – program counter – stack – data section • Process life-cycle Process =? Program main () { main () { …; …; Stack } } A() { A() { … } Heap A main … Program } Process • More to a process than just a program: – Program is static, with the potential for exection – process is a program in execution and have a state – One program can be executed several times and Process Description: Process Control Block (PCB) • Information associated with each process – – – – – – – Process state Program counter CPU registers CPU scheduling information Memory-management information Accounting information I/O status information • A process is named using its process ID (PID) • Data is stored in a process control block (PCB) Ready Queue And Various I/O Device Queues CPU Switch From Process to Process Process Creation • A process is created by another process, which, in turn create other processes, forming a tree of processes • Parent and child process • In Linux, using “ps –f”, the PPID field is the parent • The fist process is Init • After creating a child, the parent may either wait for it to finish or continue currently • Some system, the children inherit the privileges of the parents • Unix: children of the shell inherit the Process User ID and thus execute with the user’s privileges Linux Process Tree Unix Process: ps -f Process Creation • Address space – Child duplicate of parent – Child has a program loaded into it • UNIX examples – The fork() system call in Unix creates a new process. After a successful fork() call, two copies of the original code will be running. In the original process (the parent) the return value of fork() will be the process ID of the child. In the new child process the return value of fork() will be 0 – exec system call used after a fork() to replace the process’ memory space with a new program Process Creation: Unix • In Unix, processes are created using fork() • Creates and initializes a PCB and creates a new address space • Initializes the address space with a copy of the entire contents of the address space of the parent • Initializes the kernel resources to point to the resources used by parent (e.g., open files) • Places the PCB on the ready queue • Fork returns twice: Returns the child’s PID to the parent, “0” to the child Creating Processes in UNIX • Every process in UNIX has a unique identifier PID. The UNIX ps command lists each process associated with the user executing the command • Whenever a (parent) process calls a fork(), a child process is created with its own descriptor, including its own copies of the parent’s program text, data, and stack segments • The child and parent processes execute in their own separate address spaces • This means that even though they have access to the same information, when the child is created, both the child and its parent each reference its own copy of the information Process Creation: Unix • • • • How do we actually start a new program? int exec(char *prog, char *argv[]) Stops the current process Loads the program “prog” into the process’ address space • Initializes hardware context and args for the new program • Places the PCB onto the ready queue #include <stdio.h> #include <stdlib.h> main() { int pid; int rv; pid=fork(); switch(pid){ case -1: printf("Error -- Something went wrong with fork()\n"); exit(1); // parent exits case 0: printf("CHILD: This is the child process!\n"); printf("CHILD: My PID is %d\n", getpid()); printf("CHILD: My parent's PID is %d\n", getppid()); printf("CHILD: Enter my exit status: "); scanf(" %d", &rv); printf("CHILD: I'm outta here!\n"); exit(rv); default: printf("PARENT: This is the parent process!\n"); printf("PARENT: My PID is %d\n", getpid()); printf("PARENT: My child's PID is %d\n", pid); printf("PARENT: I'm now waiting for my child to exit()...\n"); wait(&rv); printf("PARENT: I'm outta here!\n"); } } #include<stdio.h> #include<stdlib.h> #include<unistd.h> main() { int pid; pid=fork(); switch(pid){ case -1: printf("Error -- Something went wrong with fork()\n"); exit(1); // parent exits case 0: execl("/bin/date","date",0); // this is the code the child runs default: wait(NULL); printf("PARENT: I'm outta here!\n"); } } System Calls System Calls • “system call” == “a function call that invokes the operating system services” • These OS services typically written in a high-level language (C or C++), are isolated from the user programs. • OS provides service to user program via system calls. System Call Interface • System calls Mostly accessed by programs via a high-level Application Program Interface (API) • Three most common APIs are Win32 API for Windows, POSIX API for POSIX-based systems (including virtually all versions of UNIX, Linux, and Mac OS X), and Java API for the Java virtual machine (JVM) • Behind the scenes, functions that make up an API typically invoke system calls. Why would an application programmer prefer programming according to an API rather than invoking actual system calls? System Calls vs. Library Routines • A system call is just what its name implies – a request for the OS do something on behalf of the user’s program – E.g., read is a system call which asks the OS to fill a buffer with data stored on a disk drive (or other device). It would be chaotic if everyone were able to access devices whenever they pleased! • A library routine does not usually need the OS to perform its work – E.g., the sin function, which computes the sine of an angle Invoke the OS • Hardware interrupt: Interrupts signal to the CPU that a hardware device has an event that needs attention, e.g. disk I/O complete, network packet arrived, keyboard input arrived, etc. • Software trap: Interrupts also signal errors or requests for OS intervention (a system call), often called an “exception” or “trap” • Explicit system call: application requests service Example of System Calls Example of System Calls • Suppose you have just compiled a program, producing, say for a Unix system, an executable file a.out. To run it, you type a.out – The shell reads the command you type – The shell then makes a system call, execve() ,asking the OS to run a.out. The OS is now running – The OS looks in its disk directory, to determine where on disk the file a.out is – The OS checks its memory-allocation table (this is just an array in the OS) to find an unused region or regions of memory large enough for a.out as well as for stack space and the heap (used for calls to calloc() and malloc()) – The OS will then load a.out into those regions of memory, and will update its memoryallocation table accordingly – The OS will check a certain section of the a.out file, in which the linker previously recorded a.out's entry point, i.e. the instruction in a.out at which execution is to begin – The OS is now ready to initiate execution of a.out – The a.out program is now running! System Call Implementation • Typically, a number associated with each system call – System-call interface maintains a table indexed according to these numbers • The system call interface invokes intended system call in OS kernel and returns status of the system call and any return values • The caller need know nothing about how the system call is implemented – Just needs to obey API and understand what OS will do as a result call – Most details of OS interface hidden from programmer by API • Managed by run-time support library (set of functions built into libraries included with compiler) Standard C Library Example • C program invoking printf() library call, which calls write() system call