3150 chapter 2 part 1
TRANSCRIPT
Lecturer: Dr. T.Y. Wong
Introduction to Operating Systems
Chapter 2, part 1Basic Process Management
Fall semester2008-2009
CEG/CSC 3150 Page 2
Outline• Process vs Program
– What are they? Any difference?
• Process Creation– How to get it done using system calls?
• Program Execution– How to execute a program?
Fall semester2008-2009
CEG/CSC 3150 Page 3
Program vs Process
What is a Program?
Fall semester2008-2009
CEG/CSC 3150 Page 4
What is a program?• What is a program?
– A program is a just a piece of code.
• But, which code do you mean?– High level language code: C, C++, etc.– Low level language code: assembly code.– Not-yet an executable: object code.– Executable: contains only machine code.
Fall semester2008-2009
CEG/CSC 3150 Page 5
Building a program – initial phase…hello.c hello.c
Pre-processorHigh-level
programminglanguage
Expandedcode
Compiler#define TXT “hello”
int main(void) {printf(“%s\n”, TXT);return 0;
}
hello.s
OptimizerAssembly
code
Program: hello.c
Fall semester2008-2009
CEG/CSC 3150 Page 6
Pre-processor• The pre-processor expands:
– #define, #include, #ifdef, #ifndef, #endif, etc.
– Try: gcc –E define.c
#define TXT “hello”
int main(void) {printf(“%s\n”, TXT );return 0;
}
int main(void) {printf(“%s\n”, “hello” );return 0;
}Pre-processor
Program: hello.c
Fall semester2008-2009
CEG/CSC 3150 Page 7
Pre-processor• Another example: the macro!
#define SWAP(a,b) { int c; c = a; a = b; b = c; }
int main(void) {int i = 10, j = 20;printf("before swap: i = %d, j = %d\n", i, j);SWAP(i, j);printf("after swap: i = %d, j = %d\n", i, j);
} Program: swap.c
int main(void) {int i = 10, j = 20;printf("before swap: i = %d, j = %d\n", i, j){ int c; c = i; i = j; j = c; };printf("after swap: i = %d, j = %d\n", i, j);
}
Pre-processor
Fall semester2008-2009
CEG/CSC 3150 Page 8
Pre-processor• How about #include?
Program: include.c
#include “header.h”
int main(void) {add_fun(1,2);return 0;
}
Program: header.h
int add_fun(int a, int b) {return (a + b);
}
int add_fun(int a, int b) {return (a + b);
}
int main(void) {add_fun(1,2);return 0;
}
Pre-processor
Fall semester2008-2009
CEG/CSC 3150 Page 9
Compiler and Optimizer• The compiler performs:
– Syntax checking and analyzing;– If there is no syntax error, construct
intermediate codes, i.e., assembly codes;
– For syntax checking topics, we have the courses: CSC3130 and CSC3120.
– For assembly language: we have the courses: CSC2510 and CSC3420.
Fall semester2008-2009
CEG/CSC 3150 Page 10
Compiler and Optimizer• The optimizer optimizes codes.
– In other words: it improves stupid codes!
– Try:• gcc –S add.c –O0 –o add_O0.s• gcc –S add.c –O1 –o add_O1.s
• Important notice: Don’t write stupid codes because there is an optimizer!
int main(void) {int x =1;x = x + 1;x = x + 1;return x;
}Program: add.c
“-O” means optimize.The number is the optimization level.
-O0: means no optimization.
Max is level 3, i.e., -O3
An example of stupid codes.
Fall semester2008-2009
CEG/CSC 3150 Page 11
Building a program – next phase…hello.ohello.s
Assembler“as”
Assemblycode
Objectcode
Linker“ld”
Static/Dynamiclibrary
Executable
hello.exelib*.a or lib*.so
Fall semester2008-2009
CEG/CSC 3150 Page 12
Assembler and Linker• The assembler assembles “hello.s” and
generates an object code “hello.o”.– A step closer to machine code.– Try: as hello.s –o hello.o
• The linker puts together all object files as well as the libraries.– There are two kinds of libraries: statically-
linked ones and dynamically-linked ones
Fall semester2008-2009
CEG/CSC 3150 Page 13
Library File• A library file is nothing special.
– It is just a bunch of function implementations.– Of course, the linker knows how to look for the
function that the C program needs.
A library file.A bunch of “dot-o” files.
Fall semester2008-2009
CEG/CSC 3150 Page 14
Library File
Static library file. Dynamic library file.
The OS will look for this file when the program runs.
A smaller program!The final
program is the combination of the above two codes.
Fall semester2008-2009
CEG/CSC 3150 Page 15
Library File• The linker also verifies if the symbols
(functions and variables) that are needed by the program are completely satisfied.– A compiled executable does not include any
shared libraries.– E.g. “gcc math.c –lm” is to link libm.so.6,
the math library.
JargonAlert
SO – Shared Object
Extra Notes
Fall semester2008-2009
CEG/CSC 3150 Page 16
How gcc compiles programs?• gcc by default hides all the intermediate steps.
– “gcc -o hello hello.c” generates the executable “hello” directly.
– “gcc -c hello.c” generates the object code“hello.o” directly.
• How about working with multiple files?
Extra Notes are the materials that the lecture will cover them, but they are not included in examinations. Nevertheless, those materials may be useful to assignments.
Extra Notes
Fall semester2008-2009
CEG/CSC 3150 Page 17
Compiling Multiple FilesStep 1.
Step 2.
Step 3.
$ gcc –o prog *.o
$ gcc –c code.c......
*.c
*.o
prog
Prepare all the source files.Important: there must be one and only one file containing the main function. Compile them into object
codes one by one. Construct the program together with all the object codes.
Extra Notes
Fall semester2008-2009
CEG/CSC 3150 Page 18
Compiling Multiple Files
int add_int(int a, int b) {return (a + b);
}
int multi_int(int a, int b) {if(b == 0)
return 0;else if(b == 1)
return a;else
return add_int(a, multi_int(a, b-1));}
gcc –Wall –c add_int.c
Program: add_int.c
Program: multi_int.c
File: add_int.o
$ gcc –Wall –c multi_int.cmulti_int.c: In function ‘multi_int’:multi_int.c:8: warning: implicit declaration of function ‘add_int’$ _
“add_int” is a new vocabulary, and gccdoesn’t know where it is.
Extra Notes
Fall semester2008-2009
CEG/CSC 3150 Page 19
Compiling Multiple Files
#include “int_header.h”
int multi_int(int a, int b) {if(b == 0)
return 0;else if(b == 1)
return a;else
return add_int(a, multi_int(a, b-1));}
int add_int(int a, int b);
Header file: int_header.h The header file provides the declaration of a function.
It is the same as saying: “there is a function named add_int()”.
You don’t have to provide the implementation in the header file. Implementation should be provided in program files.
Of course, as we know what the pre-processor will do, the declaration of the function will be written into the program file.
Extra Notes
Fall semester2008-2009
CEG/CSC 3150 Page 20
Compiling Multiple Files
#include “int_header.h”#include <stdio.h>
int main(void) {printf(“3 + 10 = %d\n”, add_int(3, 10) );printf(“3 * 10 = %d\n”, multi_int(3, 10) );return 0;
}
int add_int(int a, int b);int multi_int(int a, int b);
Header file: int_header.h
We expand the header file so that the main function knows that “there are functions called add_int() and multi_int()”.
Program: int_main.c
gcc –c add_int.cgcc –c multi_int.cgcc –c int_main.cgcc –o int_main *.o
Executable: int_main
Using double quotes means looking for the file in the current working directory.
Using “<......>”means looking for the file in the default include directories, e.g. “/usr/include/”.
Fall semester2008-2009
CEG/CSC 3150 Page 21
Conclusion on Programs• A program is just a file!
– It is static;– It may be associated with dynamically-linked
files;• “*.so” in Linux and “*.dll” in Windows.
– It may be compiled from more than one files.
Fall semester2008-2009
CEG/CSC 3150 Page 22
Process
System calls about processes
Fall semester2008-2009
CEG/CSC 3150 Page 23
Process• Process is irreplaceable in an OS.
– It associates with all the files opened by that process.– It attaches to all the memory that is allocated for it.– It contains every accounting information,
• such as the running time, current memory usage, who owns the process, etc.
• You can’t operate any things in an OS without processes.– So, this chapter is worth spending more than a month to cover.
• We start with some basic and important system calls.
Fall semester2008-2009
CEG/CSC 3150 Page 24
Process Identification• How can we identify processes from one to
another?– Each process is given an unique ID number, and is
called the process ID, or the PID.– The system call, getpid(), prints the PID of the
calling process.
$ getpidMy PID is 1234$ getpidMy PID is 1235$ getpidMy PID is 1240$ _
int main(void) {printf(“My PID is %d\n”, getpid() );return 0;
}
Program: getpid.c
Fall semester2008-2009
CEG/CSC 3150 Page 25
Process Creation• To create a process, we use the system
call fork().– 分叉 in Chinese.
Not this fork anyway…
Original execution flowof a process
The processinvokes fork().
The process splits into two!
Flow of original process
Flow of newly-created process
Fall semester2008-2009
CEG/CSC 3150 Page 26
Process Creation• So, how does fork() behave?
Process 1234
Process 1235
int main(void) {printf(“Ready to fork!\n”);fork();printf(“My PID is %d\n”, getpid() );return 0;
}
$ ./fork_example_1Ready to fork!My PID is 1234My PID is 1235$
Process 1234 is the original process, and we call it the parent process.
Process 1235 is created by the fork() system call, and we call it the child process.
Program: fork_example_1.c
Fall semester2008-2009
CEG/CSC 3150 Page 27
Process Creation
Process 1234
Process 1235
$ ./fork_example_1Ready to fork!My PID is 1234My PID is 1235$
Process 1234 is the original process, and we call it the parent process.
Process 1235 is created by the fork() system call, and we call it the child process.
• So, how does fork() behave?
• Summarize from the above printout:– Both the parent and the child processes execute the same program
code after fork().– The child process is not starting its execution from the beginning of the
program code.– The child process starts its execution after the location that fork() is
called.
Fall semester2008-2009
CEG/CSC 3150 Page 28
Process Creation• Another example. Program: fork_example_2.c
$ ./fork_example_2before fork …
1 int main(void) {2 int result;3 printf(“before fork …\n”);4 result = fork();5 printf(“result = %d.\n”, result);6 7 if(result == 0) {8 printf(“I’m the child.\n”);9 printf(“My PID is %d\n”, getpid());
10 }11 else12 printf(“I’m the parent.\n”);13 printf(“My PID is %d\n”, getpid());14 }1516 printf(“program terminated.\n”);17 }
Process1234
Fall semester2008-2009
CEG/CSC 3150 Page 29
Process Creation• Another example. Program: fork_example_2.c
$ ./fork_example_2before fork …
1 int main(void) {2 int result;3 printf(“before fork …\n”);4 result = fork();5 printf(“result = %d.\n”, result);6 7 if(result == 0) {8 printf(“I’m the child.\n”);9 printf(“My PID is %d\n”, getpid());
10 }11 else12 printf(“I’m the parent.\n”);13 printf(“My PID is %d\n”, getpid());14 }1516 printf(“program terminated.\n”);17 }
Process1234
Process1235
Process 1234 producesProcess 1235
Fall semester2008-2009
CEG/CSC 3150 Page 30
Process Creation
1 int main(void) {2 int result;3 printf(“before fork …\n”);4 result = fork();5 printf(“result = %d.\n”, result);6 7 if(result == 0) {8 printf(“I’m the child.\n”);9 printf(“My PID is %d\n”, getpid());
10 }11 else12 printf(“I’m the parent.\n”);13 printf(“My PID is %d\n”, getpid());14 }1516 printf(“program terminated.\n”);17 }
• Another example. Program: fork_example_2.c
$ ./fork_example_2before fork …
Process1234
Process1235
• Let there be only one CPU. Then…– Only one process is allowed to be executed at one time.– However, we can’t predict which process will be chosen by the
OS.– This mechanism is called Process Scheduling. It will be
discussed in details in the next chapter.
• In this case, let’s assume that Process 1234 will be executed first.
Process 1234 producesProcess 1235
Fall semester2008-2009
CEG/CSC 3150 Page 31
Process Creation• Another example. Program: fork_example_2.c
$ ./fork_example_2before fork …result = 1235.
1 int main(void) {2 int result;3 printf(“before fork …\n”);4 result = fork();5 printf(“result = %d.\n”, result);6 7 if(result == 0) {8 printf(“I’m the child.\n”);9 printf(“My PID is %d\n”, getpid());
10 }11 else12 printf(“I’m the parent.\n”);13 printf(“My PID is %d\n”, getpid());14 }1516 printf(“program terminated.\n”);17 }
Process1234
Process1235
“result” is set to the PID of the child process. Process scheduling
Fall semester2008-2009
CEG/CSC 3150 Page 32
Process Creation• Another example. Program: fork_example_2.c
$ ./fork_example_2before fork …result = 1235.I’m the parent.My PID is 1234program terminated.
1 int main(void) {2 int result;3 printf(“before fork …\n”);4 result = fork();5 printf(“result = %d.\n”, result);6 7 if(result == 0) {8 printf(“I’m the child.\n”);9 printf(“My PID is %d\n”, getpid());
10 }11 else12 printf(“I’m the parent.\n”);13 printf(“My PID is %d\n”, getpid());14 }1516 printf(“program terminated.\n”);17 }
Process1234
Process1235
Process 1234: rest in peace. Process scheduling
Fall semester2008-2009
CEG/CSC 3150 Page 33
Process Creation• Another example. Program: fork_example_2.c
$ ./fork_example_2before fork …result = 1235.I’m the parent.My PID is 1234program terminated.result = 0.
1 int main(void) {2 int result;3 printf(“before fork …\n”);4 result = fork();5 printf(“result = %d.\n”, result);6 7 if(result == 0) {8 printf(“I’m the child.\n”);9 printf(“My PID is %d\n”, getpid());
10 }11 else12 printf(“I’m the parent.\n”);13 printf(“My PID is %d\n”, getpid());14 }1516 printf(“program terminated.\n”);17 }
Process1234
Process1235
“result” is set to zero! Process scheduling
Fall semester2008-2009
CEG/CSC 3150 Page 34
Process Creation• Another example. Program: fork_example_2.c
$ ./fork_example_2before fork …result = 1235.I’m the parent.My PID is 1234program terminated.result = 0.I’m the child.My PID is 1235program terminated.$ _
1 int main(void) {2 int result;3 printf(“before fork …\n”);4 result = fork();5 printf(“result = %d.\n”, result);6 7 if(result == 0) {8 printf(“I’m the child.\n”);9 printf(“My PID is %d\n”, getpid());
10 }11 else12 printf(“I’m the parent.\n”);13 printf(“My PID is %d\n”, getpid());14 }1516 printf(“program terminated.\n”);17 }
Process1234
Process1235
Process 1235: rest in peace. Process scheduling
Fall semester2008-2009
CEG/CSC 3150 Page 35
Process Creation• fork() behaves like “cell division”.
– fork() creates the child process by cloningfrom the parent process, including…
Copied entities Description
Program counter That’s why they both execute from the same line of code after fork() returns.
Program code They are sharing the same piece of code.
Memory Including local variables, global variables, and allocated memory.
Opened file If the parent process has opened a file “A”, then the child process has also opened the file “A” automatically.
Fall semester2008-2009
CEG/CSC 3150 Page 36
Process Creation• However, fork() clones nearly all the
things from the parent process, except…
Distinct entities Parent process Child process
Return value of fork() PID of the child process Always 0.
PID number unchanged Different, not necessarily “parent PID +1”.
The parent unchanged Doesn’t have the same parent process as that of the parent process.
Running time unchanged Just created, so it is 0.
Fall semester2008-2009
CEG/CSC 3150 Page 37
Process Creation• Simple Exercise
– The command “pstree” is able to show the process relationship among the processes in the system.
– Modify “fork_example_*.c” so that you can see the process relationship of your created processes.
Fall semester2008-2009
CEG/CSC 3150 Page 38
Program Execution• fork() is rather boring…
– If a process can only duplicate itself and always runs the same program, then…
– how can we execute other programs?
• We have another set of system calls to do this job.– The exec() system call family.
Fall semester2008-2009
CEG/CSC 3150 Page 39
Program Execution• A member of exec system call family –execl()
Program: exec_example.c
$ ./exec_example_1before execl ...
Process1234
int main(void) {
printf(“before execl …\n”);
execl(“/bin/ls”, “/bin/ls”, NULL);
printf(“after execl ...\n”);
return 0;}
Program name
Program arguments
Fall semester2008-2009
CEG/CSC 3150 Page 40
Program Execution• A member of exec system call family –execl()
Program: exec_example.c
$ ./exec_example_1before execl ...exec_example_1exec_example_1.c
Process1234
Result from “/bin/ls”
int main(void) {
printf(“before execl …\n”);
execl(“/bin/ls”, “/bin/ls”, NULL);
printf(“after execl ...\n”);
return 0;}
Fall semester2008-2009
CEG/CSC 3150 Page 41
Program Execution• A member of exec system call family –execl()
Program: exec_example.c
$ ./exec_example_1before execl ...exec_example_1exec_example_1.c$ _
Process1234
int main(void) {
printf(“before execl …\n”);
execl(“/bin/ls”, “/bin/ls”, NULL);
printf(“after execl ...\n”);
return 0;}
What? Terminated?!What’d happened to these two lines of codes?
Fall semester2008-2009
CEG/CSC 3150 Page 42
Program Execution• The exec system call family is not simply a
function that “invokes” a command.– It is doing a very complex thing…
Process1234
int main(void) {
printf(“before execl …\n”);
execl(“/bin/ls”, “/bin/ls”, NULL);
printf(“after execl ...\n”);
return 0;}
Originally, I’m executing this code.
Fall semester2008-2009
CEG/CSC 3150 Page 43
Program Execution• The exec system call family is not simply a
function that “invokes” a command.– It is doing a very complex thing… file: /bin/ls
Process1234
int main(void) {
printf(“before execl …\n”);
execl(“/bin/ls”, “/bin/ls”, NULL);
printf(“after execl ...\n”);
return 0;}
Now, I change to execute the program: /bin/ls.
Fall semester2008-2009
CEG/CSC 3150 Page 44
Program Execution• The process is changing the code that it is executing and
never returns to the original code.– The last two lines of codes are therefore not executed.
• The process that calls any one of the member of the exec system call family will throw away many things, e.g.,– Memory: including local variables, global variables, and allocated
memory;– Register value: e.g., the program counter;
• But, the process will preserve something, such as– PID;– Process relationship;– Running time, etc.
Fall semester2008-2009
CEG/CSC 3150 Page 45
Program Execution• The exec system call family has 6 members and they are
named as…
Function Name
Path name File name Argument
list
Yes
Yes
Yes
letter in name p l v e
Yes
Yes
Yes
Yes
Yes
Yes
Argument Array
Original ENV
Provided ENV
execl Yes
execlp Yes
execle Yes
execv Yes Yes
execvp Yes Yes
execve Yes Yes
Fall semester2008-2009
CEG/CSC 3150 Page 46
Program Execution• Pathname vs Filename
• Argument list vs array
/home/tywong/os/shell.c
execl(“/bin/ls”, “/bin/ls”, “-l”, NULL);/bin/ls
-l
array[0]
array[1]
array[2]
NULLarray[3]
/bin/ls
execle(“/bin/ls”, array);
Environment will be covered in tutorials
Fall semester2008-2009
CEG/CSC 3150 Page 47
Program Execution• Simple Challenge
– Can you write two programs that behave as follows by using the exec system call family?
Program:yoyo1.c
Program:yoyo2.c
$ ./yoyo1running yoyo1 for the 1 time ...running yoyo2 for the 1 time ...running yoyo1 for the 2 time ...running yoyo2 for the 2 time ...running yoyo1 for the 3 time ...running yoyo2 for the 3 time .........(going indefinitely) Process
1234
Code execution is swinging back and forth.
Fall semester2008-2009
CEG/CSC 3150 Page 48
The system() call…• Someone may ask:
– Hey! I know there is a function called “system()”and it is convenient to use.
– Why would there be some stupid guys inventing the troublesome exec system call family?
int main(void) {printf(“before system …\n”);system(“ls”);printf(“after system …\n”);
}
$ ./system_examplebefore system ...exec_example_1exec_example_1.cafter system ...$ _
Program: system_example.c system(): what a great function!
Fall semester2008-2009
CEG/CSC 3150 Page 49
The system() library function call• Well…you’re reversing the order…
– “system()” is a library function call, and– it is built based on “fork()”, and exec system call
family.– (That’s why I’ve told you that system calls are not
programmer-friendly.)
int main(void) {printf(“before system …\n”);system(“ls”);printf(“after system …\n”);
}
We are now going to implement the system()function using system calls.
Program: system_example.c
Fall semester2008-2009
CEG/CSC 3150 Page 50
1 int system_ver_3150(const char *cmd_str) {2 if(cmd_str == NULL)3 return -1;45 if(fork() == 0) {6 execl("/bin/sh", "/bin/sh", "-c", cmd_str, NULL);7 fprintf(stderr, 8 "%s: command not found\n",9 cmd_str);
10 exit(-1);11 }1213 return 0;14 }1516 int main(void) {17 printf("before system_ver_3150 ...\n");18 system_ver_3150("/bin/ls");19 printf("after system_ver_3150 ...\n");20 return 0;21 }
system() Implementation
$ ./system_implement_1before system_ver_3150 ...system_implement_1system_implement_1.cafter system_ver_3150 ...$ _
Program: system_implement_1.c
“/bin/sh” is the shell program.
We actually want to execute the command:
/bin/sh -c [cmd_str]
Fall semester2008-2009
CEG/CSC 3150 Page 51
system() Implementation1 int system_ver_3150(const char *cmd_str) {2 if(cmd_str == NULL)3 return -1;45 if(fork() == 0) {6 execl("/bin/sh", "/bin/sh", "-c", cmd_str, NULL);7 fprintf(stderr, 8 "%s: command not found\n",9 cmd_str);
10 exit(-1);11 }1213 return 0;14 }1516 int main(void) {17 printf("before system_ver_3150 ...\n");18 system_ver_3150("/bin/ls");19 printf("after system_ver_3150 ...\n");20 return 0;21 }
Program: system_implement_1.c
However, when I run it for the 2nd time…
$ ./system_implement_1before system_ver_3150 ...after system_ver_3150 ...system_implement_1system_implement_1.c$ _
What’d happened?!
Fall semester2008-2009
CEG/CSC 3150 Page 52
1 int system_ver_3150(const char *cmd_str) {2 if(cmd_str == NULL)3 return -1;45 if(fork() == 0) {6 execl("/bin/sh", "/bin/sh", "-c", cmd_str, NULL);7 fprintf(stderr, 8 "%s: command not found\n",9 cmd_str);
10 exit(-1);11 }1213 return 0;14 }1516 int main(void) {17 printf("before system_ver_3150 ...\n");18 system_ver_3150("/bin/ls");19 printf("after system_ver_3150 ...\n");20 return 0;21 }
system() ImplementationProgram: system_implement_1.c
Let’s re-color the program!
Parent process
Child process
Both processes
$ ./system_implement_1before system_ver_3150 ...after system_ver_3150 ...system_implement_1system_implement_1.c$ _
$ ./system_implement_1before system_ver_3150 ...after system_ver_3150 ...system_implement_1system_implement_1.c$ _
Fall semester2008-2009
CEG/CSC 3150 Page 53
system() Implementation
$ ./system_implement_1before system_ver_3150 ...after system_ver_3150 ...system_implement_1system_implement_1.c$ _
$ ./system_implement_1before system_ver_3150 ...system_implement_1system_implement_1.cafter system_ver_3150 ...$ _
First Execution Sequence Second Execution Sequence
Parentfork()
Child
Parent
Parentfork()
Child
Parent
It is because of the OS’process scheduling…
Fall semester2008-2009
CEG/CSC 3150 Page 54
system() Implementation• Don’t forget that we’re trying to implement a system()-compatible function…– it is very weird to allow different execution orders.
• Our current problem is …how to let the child to execute first?– Sorry…we can’t control the process scheduling of the
OS to this extent.
• Then, our problem becomes…– How to suspend the execution of the parent process?– How to wake the parent up after the child is
terminated?
Fall semester2008-2009
CEG/CSC 3150 Page 55
system() Implementation1 int system_ver_3150(const char *cmd_str) {2 if(cmd_str == NULL)3 return -1;45 if(fork() == 0) {6 execl("/bin/sh", "/bin/sh", "-c", cmd_str, NULL);7 fprintf(stderr, 8 "%s: command not found\n",9 cmd_str);
10 exit(-1);11 }1213 return 0;14 }1516 int main(void) {17 printf("before system_ver_3150 ...\n");18 system_ver_3150("/bin/ls");19 printf("after system_ver_3150 ...\n");20 return 0;21 }
Put something useful here!
Program: system_implement_2.c
We introduce you the wait()system call!
system() Implementation – with wait()
Fall semester2008-2009
CEG/CSC 3150 Page 56
• The wait() system call allows a parent process to be suspended.
• wait() returns and wakes up the parent process when the status of the child process changes from– running to suspended; or– running to terminated.
• Another similar system call is waitpid().– wait() returns when one of the
children change status.– waitpid() returns when the
child specified by a PID changes status.
wait()
fork() Terminate
wake up
Case 1.
Parent is suspended.
wait()
fork() Terminate
Case 2.
no suspensionis needed.
system() Implementation – with wait()
Fall semester2008-2009
CEG/CSC 3150 Page 57
1 int system_ver_3150(const char *cmd_str) {2 if(cmd_str == NULL)3 return -1;45 if(fork() == 0) {6 execl("/bin/sh", "/bin/sh", "-c", cmd_str, NULL);7 fprintf(stderr, 8 "%s: command not found\n",9 cmd_str);
10 exit(-1);11 }12 wait(NULL);13 return 0;14 }1516 int main(void) {17 printf("before system_ver_3150 ...\n");18 system_ver_3150("/bin/ls");19 printf("after system_ver_3150 ...\n");20 return 0;21 }
When wait() returns, the parameter can tell the parent about the current status of the child process, i.e., terminated or suspended.
The parameter NULL means that “I don’t care about the child’s status”.
Look up the man page of wait by yourself.In Linux, the command is: “man 2 wait”
Program: system_implement_2.c
system() Implementation – with wait()
Fall semester2008-2009
CEG/CSC 3150 Page 58
1 int system_ver_3150(const char *cmd_str) {2 if(cmd_str == NULL)3 return -1;45 if(fork() == 0) {6 execl("/bin/sh", "/bin/sh", "-c", cmd_str, NULL);7 fprintf(stderr, 8 "%s: command not found\n",9 cmd_str);
10 exit(-1);11 }12 wait(NULL);13 return 0;14 }1516 int main(void) {17 printf("before system_ver_3150 ...\n");18 system_ver_3150("/bin/ls");19 printf("after system_ver_3150 ...\n");20 return 0;21 }
Pop Quiz!
Can we remove the “exit()” statement?
Hint. when the path “/bin/sh” cannot be found, the execl() call will continue executing this program code.
Program: system_implement_2.c
Fall semester2008-2009
CEG/CSC 3150 Page 59
Summary• A process is created by cloning.
– fork() is the system call that clones processes.– Cloning is copying: the new process inherits many
things from the parent process.– (But, where is the first process?)
• Program execution is not trivial.– A process is the place that hosts a program and run it.– exec system call family changes the program that a
process is running.– A process can run more than one program.
• as long as there is a set of programs that keeps on calling the exec system call family.