Unix Processes operating systems. The Process ID Unix identifies each process with a unique integer called a process ID. The process that executes the.

Slides:



Advertisements
Similar presentations
Recitation 8 (Nov. 1) Outline Process & job control Lab 5 Reminder Lab 5: Due Thursday Minglong Shao Office hours: Thursdays 5-6PM.
Advertisements

1 CS345 Operating Systems Φροντιστήριο Άσκησης 1.
Process Control Hua LiSystems ProgrammingCS2690Process Control Page 1 of 41.
UNIX Process Control Bach 7 Operating Systems Course Hebrew University Spring 2007.
1 Processes Professor Jennifer Rexford
1 Processes and Pipes COS 217 Professor Jennifer Rexford.
CS 311 – Lecture 14 Outline Process management system calls Introduction System calls  fork()  getpid()  getppid()  wait()  exit() Orphan process.
Exec function Exec function: - replaces the current process (its code, data, stack & heap segments) with a new program - the new program starts executing.
Process Control in Unix Operating Systems Hebrew University Spring 2004.
Process in Unix, Linux and Windows CS-3013 C-term Processes in Unix, Linux, and Windows CS-3013 Operating Systems (Slides include materials from.
Processes. Process ID (pid) Synopsis #include pid_t getpid(void) – returns the pid of the currently running process. pid_t getppid(void) – returns the.
CSSE Operating Systems
Fork and Exec Unix Model Tutorial 3. Process Management Model The Unix process management model is split into two distinct operations : 1. The creation.
Process. Process Concept Process – a program in execution Textbook uses the terms job and process almost interchangeably A process includes: – program.
Process Control. Major Requirements of an Operating System Interleave the execution of several processes to maximize processor utilization while providing.
Copyright ©: Nahrstedt, Angrave, Abdelzaher1 Processes Tarek Abdelzaher Vikram Adve.
Shell (Part 1). Process r A process is an instance of an application running r If there are two instances of an application running then there are two.
Fundamentals CIS 552. Fundamentals Low-level I/O (read/write using system calls)  Opening/Creating files  Reading & Writing files  Moving around in.
Today’s Topics Introducing process: the basic mechanism for concurrent programming –Process management related system calls Process creation Process termination.
Process. Processes A process is an abstraction for sequence of operations that implement a computation/program. A process may be manipulated, suspended,
1 Logging in to a UNIX System init ( Process ID 1 created by the kernel at bootstrap ) spawns getty for every terminal device invokes our login shell terminal.
1 Week 2 The Crunchy Shell to the Soft and Chewy Kernel… Sarah Diesburg 8/3/2010 COP4610 / CGS5765.
Creating and Executing Processes
CS 241 Section Week #2 9/9/10. 2 Topics This Section MP1 issues MP2 overview Process creation using fork()‏ Debugging tools: valgrind, gdb.
CE Operating Systems Lecture 10 Processes and process management in Linux.
Process Control Process identifiers Process creation fork and vfork wait and waitpid Race conditions exec functions system function.
Agenda  Working with Processes: Purpose Running Programs within same process (execl, execlp, execle, execv, execvp, execve) “Spawning” other process (fork,
System calls for Process management
Scis.regis.edu ● CS 468: Advanced UNIX Class 5 Dr. Jesús Borrego Regis University 1.
Linux Processes Travis Willey Jeff Mihalik. What is a process? A process is a program in execution A process includes: –program counter –stack –data section.
Copyright ©: Nahrstedt, Angrave, Abdelzaher1 Processes and Threads.
Process Management CS3320 Spring Process A process is an instance of a running program. –Not the same as “program” or “processor” Process provides.
Operating Systems Process Creation
CS4315A. Berrached:CMS:UHD1 Process Management Chapter 6.
What is a Process? u A process is an executable “cradle” in which a program may run u This “cradle” provides an environment in which the program can run,
CSCI 330 UNIX and Network Programming Unit XII: Process & Pipe Part 1.
Process Management Azzam Mourad COEN 346.
Correct C Programs. The C compiler cc [filename.c] Options include: -o [output file name] -lm to include the maths library -E to get output from preprocessor.
S -1 Processes. S -2 wait and waitpid (11.2) Recall from a previous slide: pid_t wait( int *status ) wait() can: (a) block; (b) return with status; (c)
The Process CIS 370, Fall 2009 CIS UMassD. The notion of a process In UNIX a process is an instance of a program in execution A job or a task Each process.
Tutorial 3. In this tutorial we’ll see Fork() and Exec() system calls.
System calls for Process management Process creation, termination, waiting.
CS241 Systems Programming Discussion Section Week 2 Original slides by: Stephen Kloder.
Slide 1 COMP 3438 System Programming UNIX Processes UNIX Processes (Chapters 2 & 3)
1 Unix system calls fork( ) wait( ) exit( ). 2 How To Create New Processes? n Underlying mechanism -A process runs fork to create a child process -Parent.
CS241 Systems Programming Discussion Section Week 2 Original slides by: Stephen Kloder.
4.1 Operating Systems Lecture 9 Fork and Exec Read Ch
Process Related System Calls By Neha Hulkoti & Kavya Bhat.
1 Intro to the Shell with Fork, Exec, Wait Sarah Diesburg Operating Systems CS 3430.
Linux/UNIX Programming APUE (Process Control) 문양세 강원대학교 IT 대학 컴퓨터과학전공.
CSCI 4061 Recitation 2 1.
Section 8: Processes What is a process Creating processes Fork-Exec
LINUX System : Lecture 8 Programming with Processes
Protection of System Resources
Using Processes.
Unix Process Management
CSC 382: Computer Security
UNIX PROCESSES.
Example questions… Can a shell kill itself? Can a shell within a shell kill the parent shell? What happens to background processes when you exit from.
Tarek Abdelzaher Vikram Adve Marco Caccamo
Processes in Unix, Linux, and Windows
Fork and Exec Unix Model
LINUX System Programming with Processes (additional)
Processes in Unix, Linux, and Windows
Tutorial 3 Tutorial 3.
Process Programming Interface
Processes in Unix, Linux, and Windows
EECE.4810/EECE.5730 Operating Systems
EECE.4810/EECE.5730 Operating Systems
Intro to the Shell with Fork, Exec, Wait
Presentation transcript:

Unix Processes operating systems

The Process ID Unix identifies each process with a unique integer called a process ID. The process that executes the request for creating a process is called the parent of the process. The created process is called the child process. Unix identifies each process with a unique integer called a process ID. The process that executes the request for creating a process is called the parent of the process. The created process is called the child process. operating systems

Getting the process ID #include int main ( ) { printf(“Process ID: %ld\n”, (long)getpid()); printf(“Parent process ID: %ld\n”, (long)getppid()); printf(“Process owner ID: %ld\n”, (long)getuid()); exit (0); } ex1.c operating systems

Process Termination Normal Termination return from main calling exit calling _exit Abnormal Termination calling abort terminated by a signal Normal Termination return from main calling exit calling _exit Abnormal Termination calling abort terminated by a signal calls exit cleans up, closes all files leaves files open, does not flush buffers operating systems

atexit( ) function ANSI C allows us to register up to 32 functions that are automatically called by exit( ). int atexit (void (*func) (void)); operating systems

C start-up routine main( ) user functions Kernel exit( ) I/O cleanup exit handler exit handler exec call return _exit call & return User Process

More Process Termination When a process terminates, the operating system de-allocates the resources held by the process, and notifies other processes of its demise. When a process exits, its orphaned children are adopted by the init* process. If it’s parent process is not waiting for it when it terminates, it becomes a zombie process. operating systems * launchd on OS-X (do ps –ax)

Process Creation using fork makes a copy of the parent’s system image and begins executing at the current instruction child process gets a copy of the parent’s data space, heap and stack. They do not share memory! The fork() call returns 0 to the child process, and the pid of the child to the parent process. Whether the parent or the child executes first, once the child is created, depends upon the scheduling algorithm used by the kernel. makes a copy of the parent’s system image and begins executing at the current instruction child process gets a copy of the parent’s data space, heap and stack. They do not share memory! The fork() call returns 0 to the child process, and the pid of the child to the parent process. Whether the parent or the child executes first, once the child is created, depends upon the scheduling algorithm used by the kernel. operating systems

Children Also Inherit user and group IDs controlling terminal current working directory root directory file mode creation masks all open file descriptors signal mask and dispositions environment attached shared memory segments resource limits * Keep in mind that the child process does not share these, but has copies of its own that it inherits from the parent. operating systems *

Children Are Different Because … They return a different value from fork They have different process IDs They have different parent process IDs The child does not inherit file locks set by the parent The set of pending signals for the child is set to the empty set operating systems

Try the following code #include int main ( ) { int x; x = 0; fork( ); x = 1; printf(“I am process %ld and my x value is %d\n”, (long)getpid( ), x); return 0; } What happened? fork.c

Try the following code #include int main ( ) { int x; x = 0; fork( ); x = 1; printf(“I am process %ld and my x value is %d\n”, (long)getpid( ), x); return 0; } At this point, there is one process.

Try the following code #include int main ( ) { int x; x = 0; fork( ); x = 1; printf(“I am process %ld and my x value is %d\n”, (long)getpid( ), x); return 0; } A child process is created. It has the identical code and execution environment as the parent. fork.c

Try the following code #include int main ( ) { int x; x = 0; fork( ); x = 1; printf(“I am process %ld and my x value is %d\n”, (long)getpid( ), x); return 0; } Both processes now execute this code, changing its own value of x, printing it, and exiting. The order depends on the scheduler.

Try the following code #include int main ( ) { int x; x = 0; fork( ); x = 1; printf(“I am process %ld and my x value is %d\n”, (long)getpid( ), x); return 0; } Could the child process do something different from the parent process?

Yes... test the return value of the fork( ) #include int main ( ) { int x; pid_t childpid; x = 0; childpid = fork( ); if ( childpid == -1) { perror(“failed to fork a new process”); return 1; } fork1.c

if (childpid == 0) { x = 1; printf(“I am the child, my ID = %ld, my x = &d\n”, (long)getpid( ), x); } else { x = 2; printf(“I am the parent, my ID = %ld, my x = &d\n”, (long)getpid( ), x); } return 0; } What happened?

if (childpid == 0) { x = 1; printf(“I am the child, my ID = %ld, my x = &d\n”, (long)getpid( ), x); } else { x = 2; printf(“I am the parent, my ID = %ld, my x = &d\n”, (long)getpid( ), x); } return 0; } Both processes return here from the fork( ) call. However, the return value to the parent is the pid of the child process. The return value to the child is zero.

if (childpid == 0) { x = 1; printf(“I am the child, my ID = %ld, my x = &d\n”, (long)getpid( ), x); } else { x = 2; printf(“I am the parent, my ID = %ld, my x = &d\n”, (long)getpid( ), x); } return 0; } And... the parent process executes this block The child process executes this block,

What does the following code do? int main(int argc, char *argv[ ] ) { pid_t childpid = 0; int i, n; n = atoi ( argv[1] ); for ( i = 1; i < n; i++) if (childpid = fork( ) ) break; fprintf(stderr, “i:%d process ID:%ld parent ID: %ld child ID %ld\n”, i, (long)getpid( ), (long)getppid( ), (long)childpid ); return 0; operating systems

Creates a chain of n processes int main(int argc, char *argv[ ] ) { pid_t childpid = 0; int i, n; n = atoi ( argv[1] ); for ( i = 1; i < n; i++) if (childpid = fork( ) ) break; fprintf(stderr, “i:%d process ID:%ld parent ID: %ld child ID %ld\n”, i, (long)getpid( ), (long)getppid( ), (long)childpid ); return 0; process 1 process 2 process 3 process 4 a chain for n = 4 the parent breaks out of the loop … the child continues through the loop one more time, forks a new child process and becomes the parent for the next iteration. // non zero means I’m the parent operating systems chain.c

Creating a fan of child processes int main(int argc, char *argv[ ] ) { pid_t childpid = 0; int i, n; n = atoi ( argv[1] ); for ( i = 1; i < n; i++) if (childpid = fork( ) <= 0 ) break; fprintf(stderr, “i:%d process ID:%ld parent ID: %ld child ID %ld\n”, i, (long)getpid( ), (long)getppid( ), (long)childpid ); return 0; the child breaks out of the loop … the parent continues through the loop creating a new child. This continues until the loop condition is satisfied. parent process child 1 child 2 child 3 operating systems

Run the example fan1.c a few times. What do you notice about the output? The order of the output is not in the order expected. This is because the parent just exits when it is done, the children may not have finished at this point. The order of execution depends upon how the processes were scheduled to run. Can we make the parent wait to exit until all of its children have finished?

The wait( ) system call operating systems When a fork ( ) occurs, both the parent and the child proceed with execution at the point of the fork. If the parent wants to wait for the child to finish before continuing, it executes a wait( ). wait() causes the caller to stop until the child terminates, or the caller receives a signal wait( ) returns immediately if there are no children executing the return value of wait() is: the pid of the terminating child process, or -1 if there is no child to wait for or a signal occurred errno = ECHILD indicates there was no child errno = EINTR indicates there was a signal

#include pid_t wait (int *status); returns -1 or pid of the terminating child. the return status of the child is stored in status. Test with the macros WIFEXITED - true if child terminated normally WIFSIGNALED – true if child terminated abnormally because it failed to catch a signal WIFSTOPPED - true if a child is currently stopped operating systems

operating systems Handling a wait that is interrupted by a signal #include pid_t r_wait (int* status_loc) { int retval; while ( ( (retval = wait(status_loc) ) == -1 && (errno == EINTR) ); return retval; } if the wait returns because of a signal, stay in this loop

Fixing the fan program... n = atoi(argv[1]); for (i = 1; i < n; i++) if ( (childpid = fork( ) ) <= 0) break; while (r_wait(NULL) > 0); fprintf(stderr,... ) see fan2.c

Fixing the fan program... n = atoi(argv[1]); for (i = 1; i < n; i++) if ( (childpid = fork( ) ) <= 0) break; while (r_wait(NULL) > 0); fprintf(stderr,... ) see fan2.c what happens if you replace the while statement with r_wait(NULL);

How many outputs are possible from this program? int main ( ) { pid_t childpid; childpid = fork( ); if (childpid == -1) { perror(“failed to fork”); return 1; } if (childpid == 0) fprintf(stderr, I am a child %ld\n”, (long)getpid( ) ); else if (wait(NULL) != childpid) fprintf(stderr, “A signal may have interrupted the wait\n”); else fprintf(stderr, I am a parent %ld\n”, (long)getpid( ) ); return 0; }

int main ( ) { pid_t childpid; childpid = fork( ); if (childpid == -1) { perror(“failed to fork”); return 1; } if (childpid == 0) fprintf(stderr, I am a child %ld\n”, (long)getpid( ) ); else if (wait(NULL) != childpid) fprintf(stderr, “A signal may have interrupted the wait\n”); else fprintf(stderr, I am a parent %ld\n”, (long)getpid( ) ); return 0; } 1. The fork fails, the program will output “failed to fork”

int main ( ) { pid_t childpid; childpid = fork( ); if (childpid == -1) { perror(“failed to fork”); return 1; } if (childpid == 0) fprintf(stderr, I am a child %ld\n”, (long)getpid( ) ); else if (wait(NULL) != childpid) fprintf(stderr, “A signal may have interrupted the wait\n”); else fprintf(stderr, I am a parent %ld\n”, (long)getpid( ) ); return 0; } 2. The child prints its message, but then the parent catches a signal before the child actually returns. I am a child 3427 child code parent code a signal may have interrupted this call

int main ( ) { pid_t childpid; childpid = fork( ); if (childpid == -1) { perror(“failed to fork”); return 1; } if (childpid == 0) fprintf(stderr, I am a child %ld\n”, (long)getpid( ) ); else if (wait(NULL) != childpid) fprintf(stderr, “A signal may have interrupted the wait\n”); else fprintf(stderr, I am a parent %ld\n”, (long)getpid( ) ); return 0; } 3. The child prints its message and returns. The wait returns normally I am a child 3427 I am a parent 3424 child code parent code

int main ( ) { pid_t childpid; childpid = fork( ); if (childpid == -1) { perror(“failed to fork”); return 1; } if (childpid == 0) fprintf(stderr, I am a child %ld\n”, (long)getpid( ) ); else if (wait(NULL) != childpid) fprintf(stderr, “A signal may have interrupted the wait\n”); else fprintf(stderr, I am a parent %ld\n”, (long)getpid( ) ); return 0; } 4. The parent catches a signal and prints its “signal” message before the child prints its message. A signal may have interrupted the call parent code child code I am child 3427

int main ( ) { pid_t childpid; childpid = fork( ); if (childpid == -1) { perror(“failed to fork”); return 1; } if (childpid == 0) fprintf(stderr, I am a child %ld\n”, (long)getpid( ) ); else if (wait(NULL) != childpid) fprintf(stderr, “A signal may have interrupted the wait\n”); else fprintf(stderr, I am a parent %ld\n”, (long)getpid( ) ); return 0; } 5. The parent catches a signal before the child prints its message, but it prints its “signal” message after the child prints. parent code child code I am child 3427 A signal may have interrupted this call

Status Values The status parameter of the wait( ) system call is an int* If it is not NULL, the return status of the child is stored in the integer variable pointed to. The child status is returned by return n exit (n) A zero value indicates that the child process exited normally.

Keep in mind that the wait( ) system call blocks if there are any child processes executing. What if we want to see if a child process has terminated, but not block?

waitpidwaitpid pid_t waitpid (pid_t pid, int *stat_loc, int options); returns the pid of the child or -1 if there is an error, or 0 if there are children to be waited for, but none of them are done the process to be waited for, or -1 if you want to wait for any child process to finish. the interesting option is WNOHANG which causes waitpid to return even if there is there is no child for which status is available. operating systems

#include int status; pid_t waited_for_pid; … while (waited_for_pid = waitpid (-1, &status, WNOHANG) ) if ((waited_for_pid == -1) && (errno != EINTR) break; this code segment waits for any child, without blocking, if there are no children with status available. It stays in the loop if the waitpid is interrupted by a signal. operating systems

PollingPolling A parent can wait for a child to finish by using the wait or waitpid calls. However, what does a child do when it wants to wait for the parent to finish? operating systems while (getppid( ) != 1) sleep(1); this type of code is called polling, and burns up cpu time To avoid race conditions and polling, we use signals why?

Zombie Process If a child process completes before its parent does, some vestige of the process has to hang around so that the parent can determine its termination status with a wait( ). This is called a zombie process. operating systems

Orphan Processes What happens if the parent process exits before its child process does. The child has to have a parent, so it is adopted by the init process. operating systems

Reminder - forks are used When a process wants to duplicate itself so that the parent and the child can execute different parts of the program simultaneously. This is common for server software. When a process wants to execute a different program. This is common for shells. operating systems

exec( ) operating systems fork ( ) – creates a copy of the calling process. exec ( ) – overlays the calling process with a new process. Traditional approach is for the parent to fork( ) a new process, which then does an exec to overlay the process with the new program. The parent then stays around. The exec copies a new executable into the process image. The program text, variables, stack, and the heap are overwritten.

Process A program A fork( ); rhtj,nn vio nlk;jh eahg jkfsdajhfk.ADFSkfdnkZX dfjklA:LDhlADjlkd fakJLc dsakl;naS fork( ) { exec( ) ‘ fdsnjhkjsd } hjfhksa } jkds,n,ds mkfl jmhjsd fhjsdf ‘jkfg { kjl;sdfdsf fdsjklsdf Process B program A rhtj,nn vio nlk;jh eahg jkfsdajhfk.ADFSkfdnkZX dfjklA:LDhlADjlkd fakJLc dsakl;naS fork( ); { exec( ); ‘ fdsnjhkjsd } hjfhksa } jkds,n,ds mkfl jmhjsd fhjsdf ‘jkfg { kjl;sdfdsf fdsjklsdf exec( ) rhtj,nn vio nlk;jh eahg jkfsdajhfk.ADFSkfdnkZX dfjklA:LDhlADjlkd fakJLc dsakl;naS hlhkasf jghji fhnjkjsdf fdsnjhkjsd fht9 hjfhksa } jkds,n,ds mkfl jmhjsd fhjsdf ‘jkfg { kjl;sdfdsf fdsjklsdf program c

execl( ) This family of functions is useful when the number of command line arguments is known at compile time #include int execl(const char *path, const char *arg0, const char *arg1, … const char *argn, NULL); path to the executable first command line argument second command line argument final command line argument A NULL pointer operating systems

ExampleExample int main ( ) { pid_t childpid; int stat; if ((childpid = fork() == -1) { perror(“Error in fork.”); exit(1); } else if (childpid == 0) { if (execl(“/bin/ls”, “ls”, “-l”, NULL) < 0) { perror(“Error in exec.”); exit(1); } else if (childpid != wait(&stat)) { perror(“A Signal occurred before the child exited.”); exit(1); } return (0); } This is child code. It replaces the current process with /bin/ls This is parent code. operating systems dols.c

Variations of execl #include int execlp(const char *file, const char *arg0, const char *arg1, …, const char *argn, NULL); int execle (const char *path, const char *arg0, const char *arg1, …, const char argn, NULL, char *const envp[]); This variation uses the PATH variable to locate the executable This variation passes a pointer to an array of strings that holds a new environment for the command. operating systems

execv( ) This family of functions is used to pass command line arguments to the new process #include int execv(const char *path, char *const argv[]); path to the executable an argument array, just as if these had come from the command line. You have to build this! execv also has execvp and execve variations. operating systems

int main (int argc, char *argv[]) { pid_t childpid; int status; if ((childpid = fork()) == -1) { perror("The fork failed"); exit(1); } else if (childpid == 0) { if (execvp(argv[1], &argv[1]) <0) { perror("The exec failed"); exit(1); } } else { while(childpid != wait(&status)) { if ((childpid == -1) && (errno != EINTR)) break; } } return (0); } execvp constructs the pathname using the PATH environment variable. argv[0] is the first argument when this command is executed, so &argv[1] points to the two tokens ls and -l create the executable myexec. Then typing myexec ls –l will result in this function calling ls -l the parent waits for the child to terminate. operating systems

A Shell is a command interpreter which prompts for commands, reads the commands from standard input, forks children to execute the commands, and waits for the children to finish. When you end a command with &, the shell creates the child process, but does not wait for it to finish. The child is known as a background process. operating systems

A daemon is a background process that runs indefinitely. operating systems

Terminal Log-ins /etc/ttys contains one line per terminal device when the system is bootstrapped, the kernel creates process 1, the init process init reads /etc/ttys and for each terminal device in the file, it forks a new process and execs the getty program operating systems * launchd on OS-X (do ps –ax) *

init... fork (once per terminal) getty exec operating systems

getty opens a terminal device and issues a login message When a user name is entered, getty execs login login gets the password and checks to see if all is well If it is, login changes to the user’s home directory, changes ownership of the terminal, initializes the environment, and execs the shell specified for the user. operating systems

init getty exec fork login exec shell exec operating systems

Process Groups In addition to having a process ID, each process belongs to a process group. A process group is a collection of one or more processes. operating systems Session A session is a collection of one or more process groups.

An Example using redirection This program exploits the fact that open file descriptors are preserved across fork and exec calls. operating systems

#include int main( ) { int ch; while ((ch = getchar( ) ) != EOF) { putchar(toupper(ch)); } exit(0); } This program is written as a filter. It reads in text and converts it to upper case. upper operating systems upper.c

What if we want to invoke this filter from inside of a program? operating systems

#include int main ( int argc, char *argv[]) { char *filename; filename = argv[1]; // now call freopen to open the file on standard input if (!freopen(filename, "r", stdin)) { printf("Could not re-direct file to stdin\n"); exit(1); } // now exec the upper program execl( "./upper", "upper", 0); // since the exec replaces the current program, the following // lines are not executed unless the exec fails. perror("could not exec./upper"); exit(3); } Closes the file descriptor for stdin Then re-opens the file as stdin execupper.c