Creating Process with fork()
fork()creates a new process (child) from the calling process (parent)
i.e. it makes a copy of the current process- Both parent and child continue running same code, starting after the
fork()line
- Both parent and child continue running same code, starting after the
fork()can return different values:0in the child process (because 0 is not valid PID)>0(child’s PID) in the parent process-1error (failed to create process)
Thus, you can write code that behaves differently in parent vs child:
int pid = fork();
if (pid == -1) {
printf("fork failed\n");
} else if (pid == 0) {
// child
printf("I am the child process!\n");
} else {
// parent
printf("I am the parent process, my child has PID %d\n", pid);
}Memory in Parent vs Child Process
- When
fork()is used, both the parent and child process get an exact copy of the same memory- Variables, stack and heap are duplicated
- After
fork(), the two processes won’t see changes to the memory that the other makes
Modern OSes don’t copy everything immediately and instead wait till one of the programs changes something → this saves time and memory
andexec().png)
Running New Programs with exec()
- Sometimes we don’t want child program to run same code as parent
- Using
exec()we can replace the child program with another program- PID remains the same
- Note: does not always needed to be called in child program
int main(void) {
int pid = fork();
if (pid == 0) {
// child process
char *args[] = {"ls", "-l", NULL};
execvp("ls", args); // replace child with "ls -l"
} else {
// parent process
wait(NULL); // wait for child to finish
printf("Child finished!\n");
}
return 0;
}Above, fork() makes child program, execvp() replaces child program with ls -l which lists files in a directory
- There are many different variants of
exec()l= “list” (you pass arguments one by one)v= “vector” (you pass arguments as an array/vector)p= search your$PATHfor program instead of giving full path
Above,
"ls"is the program name andargsis an array of argument passed to the program
Waiting for Child Process
- Using
wait(&status), the parent process can pause until the child process has finished executing- Once the child has finished running, the exit value is passed through
status
- Once the child has finished running, the exit value is passed through
- When child calls
exit(value), the value it returns represents its status:exit(0)→ successexit(1)(or other non-zero) → failure