1 / 48

Process in Unix OS

Process in Unix OS. Program Vs Process. Program is just a file containing instructions and data These instructions while in execution constitute a process.

kai-clayton
Download Presentation

Process in Unix OS

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Process in Unix OS

  2. Program Vs Process • Program is just a file containing instructions and data • These instructions while in execution constitute a process. • A process is an execution environment that consists of instructions, user-data and system-data segments as well as resources acquired at run time.

  3. Process • Each process in Unix is identified by a unique process id called pid. • Process IDs are usually 16-bit numbers that are assigned sequentially by UNIX as new processes are created. • Every process has a parent process which creates that process. • All the processes in the system are arranged in a tree like structure having init process at the root. • The parent process id (ppid) is the process id of the parent process.

  4. getpid() & getppid() system calls • To obtain current process id, use getpid() system call. • To obtain parent process id, use getppid() system call.

  5. #include <stdio.h> #include <unistd.h> #include<sys/types.h> int main() { pid_t pid,ppid; pid = getpid(); ppid = getppid(); printf("\nProcess id: %d",pid); printf("\nParent Process id: %d\n",ppid); return 0; }

  6. Run on the same window [Mayuri@localhost processes]$ ./a.out Process id: 6590 Parent Process id: 6570 [Mayuri@localhost processes]$ ./a.out Process id: 6598 Parent Process id: 6570 Run on different window [Mayuri@localhost processes]$ ./a.out Process id: 6617 Parent Process id: 6603 [Mayuri@localhost processes]$

  7. Vewing Active Processes: ps command [Mayuri@localhost processes]$ ps PID TTY TIME CMD 6603 pts/2 00:00:00 bash 6624 pts/2 00:00:00 ps

  8. Context of a process • Many processes are running in the Unix system. • Memory can not hold all the processes at the same time. • Hence the system needs to replace one process from main memory and introduce another process in its place. • The replacement of one process with another is called context-switching. • The context of a process includes all the information that the OS needs to restart a process after a context switch. Typically, this includes PC, stack, registers, executable code etc

  9. Fork() and exec() system calls • Fork() • It creates a new process which is an identical copy of an existing process. • The newly created process will contain all the instructions and data of its parent process. • Hence it executes the same parent process. • Exec() • This on the other hand re-initializes the existing process with some other designated program. • It does not create a new process. • It merely flushes the current context of a program and loads a new context (new program). • exec() call is the only way to execute programs in UNIX. In fact, the kernel boots itself using the exec() call. • fork() is the only way to create new processes in UNIX

  10. System() function call • The System() call creates a new process that will execute a designated program and context of the new process is loaded. • It is used to execute a unix command from C program • The syntax is #include <stdlib.h> int system(const char *command); • System() function is a C library function which in turn uses Unix system call to do its job. • It creates a new process for the command to be executed by using fork() system call. • Then it calls exec() system call which executes the unix command mentioned in the system() function.

  11. The following program gives the output of the command “ls –l” #include <stdlib.h> int main () { int return_value; return_value = system (“ls -l /”); return return_value; }

  12. Program Components: Arguments and Environment • An executing Unix program always receives two collection of data from the process that invoked it. • Arguments (command line arguments) • It holds user data • Environment • It holds system data • In C programs, these are in the form of array of character pointers. • The count of arguments is stored in variable “argc” and pointers to character array (arguments) are stored in argv[]. This is terminated by NULL pointer. • In addition, a global variable called “environ” that points to array of environment strings is also passed to main() function. extern char **environ; /* Environment Array */

  13. Program to see the current execution environment: it gives listing of all the environment variables # include<stdio.h> extern char **environ; int main(int argc, char *argv[]) { int i; printf("Arguments to this Program\n"); for(i=0;i<argc;i++) { printf("%s\n",argv[i]); } printf("Environment Listing of this program\n"); for(i=0;environ[i]!=NULL;i++) { printf("%s\n",environ[i]); } return 0; }

  14. Output: $./a.out 1 2 3 4 5 Arguments to this Program ./a.out 1 2 3 4 5 Environment Listing of this program ORBIT_SOCKETDIR=/tmp/orbit-Mayuri HOSTNAME=localhost.localdomain IMSETTINGS_INTEGRATE_DESKTOP=yes GPG_AGENT_INFO=/tmp/keyring-jWyvqj/gpg:0:1 TERM=xterm SHELL=/bin/bash XDG_SESSION_COOKIE=267e035611a62169555037150000000e-1315307637.293523-1578328767 HISTSIZE=1000 WINDOWID=71303171 GNOME_KEYRING_CONTROL=/tmp/keyring-jWyvqj IMSETTINGS_MODULE=none USER=Mayuri ... ... ...i

  15. getenv() function: int main(void) { char *s; s = getenv(“LOGNAME”); if(s==NULL) printf(“Variable Not Found\n”); else printf(“Value is %s \n”, s); return 0; }

  16. Exec Family • Exec system calls are a set six system call of the form execAB • execl • execv • execlp • execvp • execle • execve

  17. execl() system Call • It execute file with arguments explicitly in call. • Syntax int execl ( const char *path,/* Complete Program pathname */ const char *arg0,/* First Argument(filename) */ const char *arg1, /* Second Argument(optional) */ … /* Remaining Arguments (if any) */ (char *) NULL /* Arg list terminator */ ); /* Returns -1 on error (sets errno) */

  18. execl() system call • After the call to execl() the context of the process is overwritten. • Previous code is replaced by the code/instructions of the executable in ‘path’. • User data is also replaced with the data of the program in ‘path’ thereby reinitializing the stack. • And the new program begins to execute from its main function. • New program accesses the arguments of new program which are mentioned in execl() through its ‘argc’ and ‘argv’ arguments of the main function. • Environment pointed to by ‘environ’ is also passed to the new program.

  19. Return of execl() system call • Recall that the return address of any function is saved in the stack. • The return address is popped from the stack while a function returns. • But here the stack is reinitialized with the data of the new program and the old program’s data is lost. • So there is no way to pop the return address and hence there is no way to return from execl() call if the call is successful.

  20. execl() example to invoke user executable #include<stdio.h> #include<stdlib.h> #include<string.h> int main(int argc,char *argv[]) { int sum=0; int i; if(argc != 4) { printf("invalid argument\n"); exit(0); } for(i=0;i<argc;i++) sum = sum + atoi(argv[i]); printf("sum = %d\n",sum); } #include<stdio.h> #include<unistd.h> int main() { execl("./sum","sum","100","200","300",(char *)NULL); printf("execl call unsuccessful\n"); }

  21. execl() Example to invoke UNIX commands # include<stdio.h> # include<unistd.h> int main(int argc, char ** argv){ printf("Hello World!"); execl("/bin/echo","echo","Print","from","execl",(char *)NULL); return 0; } In the above program “Hello World!” is not printed Reason: Printf() function in C does not immediately prints the data on stdout but it buffers it till the next printf() statement or program exit.

  22. Forcefully flush the data from the buffer to stdout in the following way: int main(int argc, char ** argv){ printf("Hello World!"); fflush(stdout); execl("/bin/echo","echo","Print","from","execl",(char *)NULL); return 0; }

  23. Other exec system calls • The other exec calls are very similar to execl(). They provide the following three features that are not available in execl(). • Arguments can be put into a vector/array instead of explicitly listing them in the exec call. This feature is useful if the arguments are not known at compile time. • Searching for an executable using the value of the PATH environment variable. When this feature is used we don’t have to specify the complete path in the exec call. • Manually passing an explicit environment pointer instead of automatically using environ.

  24. Exec Family • Exec system calls are a set six system call of the form execAB. • Where ‘A’ is either ‘l’ (the arguments are directly in the call (list)) or ‘v’ (the arguments are in an array (vector)). • ‘B’ if present is either ‘p’ or ‘e’. • ‘p’ indicates that the PATH environment variable should be used to find the program to be executed. • ‘e’ indicates that a particular environment should be used which is passed as an argument.

  25. The six exec system calls • execl: execute file with arguments explicitly in call • execv : execute file with argument vector • execlp: execute file with arguments explicitly in call and PATH search • execvp: execute file with argument vector and PATH search • execle: execute file with argument list and manually passed environment pointer • execve: execute file with argument vector and manually passed environment pointer

  26. int execv ( const char *path, /* Program pathname */ char* const argv[] /* Argument vector */ ); int main(int argc,char *argv[]) { execv("./sum",argv); printf("execl call unsuccessful\n"); }

  27. int execvp ( • const char *file, /* Program filename */ • char* const argv[] /* Argument vector */ • ); • int execve ( • const char *path, /* Program pathname */ • char *const argv[], /* Argument vector */ • char *const envv[] /* Environment vector */ • );

  28. int execlp ( const char *file, /* Program filename */ const char *arg0, /*First Argument(filename) */ const char *arg1, … (char *) NULL /* Arg list terminator */ ); int execle ( const char *path, /* Program pathname */ const char *arg0, /*First Argument(filename) */ const char *arg1, … (char *) NULL, /* Arg list terminator */ char *const envv[] /* Environment vector */ );

  29. fork() system call • fork() call creates a “new” process. • The child process’ context will be the same as the parent process. • After a fork() call, two copies of the same context exist, one belonging to the child and another to the parent. • Contrast this to exec(), where a single context will exist because of child context over-writing the parent. • # include<unistd.h> • int fork(void); • /*Returns child process-ID and 0 on success and -1 on error */

  30. Return value of fork() system call • After fork() returns both the child and the parent receive the return value. • The child receives a 0 as return value from fork() and the parent receives the process-ID of the child.

  31. Program to demonstrate simple fork() usage 1# include<stdio.h> 2int main(void){ 3 printf(“************ Before Fork************\n”); 4 system(“ps”); 5 6 fork(); 7 8 printf(“************ After Fork *************\n”; 9 system(“ps”); 10 return 0; 11}

  32. output ************ Before Fork************ PID TTY TIME CMD 2967 pts/0 00:00:00 bash 2990 pts/0 00:00:00 a.out 2991 pts/0 00:00:00 ps ************ After Fork ************* ************ After Fork ************* PID TTY TIME CMD PID TTY TIME CMD 2967 pts/0 00:00:00 bash 2967 pts/0 00:00:00 bash 2990 pts/0 00:00:00 a.out 2990 pts/0 00:00:00 a.out 2992 pts/0 00:00:00 a.out 2992 pts/0 00:00:00 a.out 2993 pts/0 00:00:00 ps 2993 pts/0 00:00:00 ps 2994 pts/0 00:00:00 ps 2994 pts/0 00:00:00 ps

  33. Modified code 1# include<stdio.h> 2int main(void){ 3 int ret; 4 printf(“************ Before Fork************\n”); 5 system(“ps”); 6 7 ret=fork(); 8 if(ret==0){ 9 printf(“************ After Fork *************\n”; 10 system(“ps”); 11 } 12 else if(ret>0) 13 wait(); 14 return 0; 15}

  34. output ************ Before Fork************ PID TTY TIME CMD 2967 pts/0 00:00:00 bash 3005 pts/0 00:00:00 a.out 3006 pts/0 00:00:00 ps ************ After Fork ************* PID TTY TIME CMD 2967 pts/0 00:00:00 bash 3005 pts/0 00:00:00 a.out 3007 pts/0 00:00:00 a.out 3008 pts/0 00:00:00 ps

  35. int main(void) { pid_t pid; printf("************ Before Fork************\n"); system("ls -l"); pid = fork(); if(pid == 0){ printf("************ After Fork *************\n"); system("ps"); } else if (pid > 0) wait(); return 0; } fork() example 2

  36. [Mayuri@localhost processes]$ ./a.out ************ Before Fork************ total 60 -rwxrwxr-x. 1 Mayuri Mayuri 6937 Sep 13 16:30 a.out -rw-rw-r--. 1 Mayuri Mayuri 310 Sep 6 16:48 env.c -rw-rw-r--. 1 Mayuri Mayuri 145 Sep 6 17:06 execL.c -rw-rw-r--. 1 Mayuri Mayuri 219 Sep 13 15:50 execlp.c -rw-rw-r--. 1 Mayuri Mayuri 219 Sep 5 15:41 pid_ppid.c -rwxrwxr-x. 1 Mayuri Mayuri 6919 Sep 13 13:16 sum -rw-rw-r--. 1 Mayuri Mayuri 280 Sep 13 13:16 sum.c -rw-rw-r--. 1 Mayuri Mayuri 326 Sep 2 13:03 system1.c ************ After Fork ************* PID TTY TIME CMD 2806 pts/0 00:00:00 bash 3565 pts/0 00:00:00 a.out 3567 pts/0 00:00:00 a.out 3568 pts/0 00:00:00 ps

  37. int main(int argc, char *argv[]){ int pid; printf("*****before fork****\n "); system("ps"); pid = fork(); if(pid == 0) { printf("*****after fork****\n "); printf("child pid = %d\n",pid); //execl("/bin/echo","echo","hello","world",(char *)NULL); execlp("echo","echo","hello","world",(char *)NULL); } else { printf("parent pid = %d\n",pid); wait(); } return 0; } Using exec system call

  38. [Mayuri@localhost processes]$ ./a.out *****before fork**** PID TTY TIME CMD 2806 pts/0 00:00:00 bash 4196 pts/0 00:00:00 a.out 4197 pts/0 00:00:00 ps parent pid = 4198 *****after fork**** child pid = 0 hello world output

  39. What is a Shell? A shell is a program that takes an input string from the user and executes some program corresponding to the input string. To execute any program, we have to give it environment and arguments The arguments to the program are obtained by parsing the input string Assume the environment variable used is the default  For simplicity, let’s assume that the shell does not handle piping, background processes, sequential execution or redirection. Hence a valid input to such a shell can consist only of a sequence of words separated by blanks or tabs. E.g $cal 3 2011 or $wc program.c Implementing a Shell – version 1

  40. int main() { char *argv[MAXARG]; int argc,token; int i=0; while(1){ printf("@"); token = make_args(&argc,argv,MAXARG); if(token && argc > 0) { execvp(argv[0],argv); printf("Execution unsuccessful!.......\n"); printf("%s\n",strerror(errno)); } else printf("Error Constructing Arguments\n"); }//end of while() return 0; } #include<stdio.h> #include<string.h> #include<errno.h> #include<unistd.h> #define MAXARG 20 #define MAXCMD 100 //this function separates the input string into a argv[] array

  41. int make_args(int *argc_ptr,char *argv[],int max) { static char cmd[MAXCMD]; char *cmd_ptr; int i=0; fgets(cmd,sizeof(cmd),stdin); cmd_ptr = cmd; for(i=0;i<max;i++) { argv[i] = strtok(cmd_ptr," \t\n"); if(argv[i] == NULL) break; cmd_ptr = NULL; } *argc_ptr = i; return 1; } make_args()

  42. [Mayuri@localhost processes_new]$ ./a.out @ls Prog1.c a.out filename.txt [Mayuri@localhost processes_new]$ ./a.out @cal 12 2011 December 2011 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 [Mayuri@localhost processes_new]$ ./a.out @ wc shell_v1.c 46 81 744 shell_v1.c output

  43. int main() { char *argv[MAXARG]; int argc,token; int i=0; while(1) { printf("@"); token = make_args(&argc,argv,MAXARG); if(token && argc > 0) execute(argc,argv); else printf("Error Constructing Arguments\n"); } return 0; } Implementing Shell version – 2 (using fork and exec)

  44. void execute(int argc,char *argv[]) { int pid; switch(pid = fork()) { case 0: execvp(argv[0],argv); printf("child not successful!......\n"); exit(0); case -1: printf("unable to create a child!......\n"); break; default: wait(NULL); } }

  45. fork() calls are enormously costly in terms of computing resources. A clone of the parent’s context is made which involves copying of the data segment. Copy of instruction segment (code) is not made because the segment is read-only and hence is shared between parent and child. The data segment can be very huge. if fork() is immediately followed by exec() then it overwrites the existing data and code segments. Hence copying data segment is wasted. A scheme that overcomes this handicap is called the “copy-on-write” scheme. In this scheme, after fork() the parent and the child share the same data segment as long as the data segment is unmodified. When the parent or child modifies a particular page, a copy of only that page is made. So, there would be two copies of modified pages while the unmodified pages would be shared. vfork() is an obsolete call and has exactly the same syntax as fork(). The only difference between vfork() and fork() is that vfork() does not make a copy of the data segment. Forking Cost

  46. Repeated fork() calls (also known as fork bombs), can eventually lead to resource exhaustion and may collapse the system. Program to demonstrate repeated forking int main(void){ int cnt=0; int pid;   for(cnt=0;cnt<3;cnt++){ pid=fork(); printf("Now in process %d\n",getpid()); }   return 0; } how many new processes would be created? Fork bombs

  47. The number of children would be : 7 In the first iteration, only the parent process exists and it creates a single child, C1. In the second iteration both P and C1 exist and each fork to give C3 and C2 respectively In the last iteration P,C1,C2,C3 exist and each fork to give C7,C6,C4,C5 respectively.

  48. int main(void){   int cnt=0; int pid;   for(cnt=0;cnt<3;cnt++){ pid=fork(); if(pid==0) continue; else break; }   printf("Process %d\n",getpid()); return 0; } Program to demonstrate controlled forking

More Related