XXX Fork
XXX Fork
Topics
User
Space
Keyboard
HW CPU Memory Disk
Monitor
Computer systems
user’s view
• Informal definition:
A process is a program in execution.
• ps command
– Standard process attributes
pid = fork();
if (pid == -1) {
fprintf(stderr, "fork failed\n");
exit(1);
}
if (pid == 0) {
printf(“This is the child\n");
exit(0);
}
if (pid > 0) {
printf(“This is parent. The child is %d\n", pid);
exit(0);
}
Points to Note
• fork() is called once …
• … but it returns twice!!
– Once in the parent and
– Once in the child
• Fork() basically duplicates the parent process image
– Both processes are exactly the same after the fork()
call.
• Are there any dependence between the two processes?
– Provide a way to distinguish the parent and the child.
• When the main program executes fork(), an identical
copy of its address space, including the program and
all data, is created.
• System call fork() returns the child process ID to the
parent and returns 0 to the child process.
/* ----------------------------------------------------------------- */
/* PROGRAM fork-01.c */
/* This program illustrates the use of fork() and getpid() system */
/* calls. Note that write() is used instead of printf() since the */
/* latter is buffered while the former is not. */
/* ----------------------------------------------------------------- */
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
void main(void)
{
pid_t pid;
int i;
char buf[BUF_SIZE];
fork();
pid = getpid();
for (i = 1; i <= MAX_COUNT; i++) {
sprintf(buf, "This line is from pid %d, value = %d\n", pid, i);
write(1, buf, strlen(buf));
}
}
• If the call to fork() is executed successfully, Unix will
make two identical copies of address spaces, one
for the parent and the other for the child.
• Both processes will start their execution at the next
statement following the fork() call. In this case, both
processes will start their execution at the assignment
statement.
• Both processes start their execution right after the system call fork().
• Since every process has its own address space, any modifications will be
independent of the others. In other words, if the parent changes the value
of its variable, the modification will only affect the variable in the parent
process's address space.
• Other address spaces created by fork() calls will not be affected even
though they have identical variable names.
Process ID 3456 may be the one assigned to the parent or the child. Due to the fact
that these processes are run concurrently, their output lines are intermixed in a rather
unpredictable way. Moreover, the order of these lines are determined by the CPU
scheduler. Hence, if you run this program again, you may get a totally different result.
/* ----------------------------------------------------------------- */
/* PROGRAM fork-02.c */
void ChildProcess(void)
/* This program runs two processes, a parent and a child.
Both of */ {
/* them run the same loop printing some messages. Note int i;
that printf()*/
/* is used in this program. */
for (i = 1; i <= MAX_COUNT; i++)
/* ----------------------------------------------------------------- */
printf(" This line is from child, value = %d\n",
#include <stdio.h>
i);
#include <sys/types.h> printf(" *** Child process is done ***\n");
}
#define MAX_COUNT 200
void ParentProcess(void)
void ChildProcess(void); /* child process prototype
*/
{
void ParentProcess(void); /* parent process int i;
prototype */
for (i = 1; i <= MAX_COUNT; i++)
void main(void) printf("This line is from parent, value = %d\n",
{ i);
pid_t pid; printf("*** Parent is done ***\n");
}
pid = fork();
if (pid == 0)
ChildProcess();
else
ParentProcess();
}
• When the main program executes fork(), an identical copy of its address space,
including the program and all data, is created.
• System call fork() returns the child process ID to the parent and returns 0 to the child
process.
• The following figure shows that in both address spaces there is a variable pid. The one
in the parent receives the child's process ID 3456 and the one in the child receives 0.
• In the parent, since pid is non-zero, it calls
function ParentProcess(). On the other hand, the child has a
zero pid and calls ChildProcess() as shown below:
• Due to the fact that the CPU scheduler will assign a time
quantum to each process, the parent or the child process
will run for some time before the control is switched to
the other and the running process will print some lines
before you can see any line printed by the other process.
• Therefore, the value of MAX_COUNT should be large
enough so that both processes will run for at least two or
more time quanta.
• If the value of MAX_COUNT is so small that a process can
finish in one time quantum, you will see two groups of
lines, each of which contains all lines printed by the same
process.
Points to Note
• vfork was created to be a more efficient fork for the case where the
new process intends to do an exec right after the fork.
After doing a vfork, the parent and child processes share the same
data space, and the parent process is suspended until the child
process either execs a program or exits.
Parent
Running a command
without killing the
process?
Fork(…)
Parent Child
Running a command
without killing the
process,
Fork(…)
Parent Child
Exec(…)
New program
image
in execution
Terminating a process
* Signal
A signal is a notification to a process that an event has
occurred. Signals are sometimes called “software
interrupts”.
* Features of Signal
- Signal usually occur asynchronously.
- The process does not know ahead of time exactly when a
signal will occur.
- Signal can be sent by one process to another process (or to
itself) or by the kernel to a process.
Sources for Generating
Signals
* Hardware
- A process attempts to access addresses outside its own
address space.
- Divides by zero.
* Kernel
- Notifying the process that an I/O device for which it has
been waiting is available.
* Other Processes
- A child process notifying its parent process that it has
terminated.
* User
- Pressing keyboard sequences that generate a quit, interrupt
or stop signal.
Three Courses of Action
• Why processes?
• What is process context?
• How to check processes in UNIX?
• What does fork() do? What is its return value?
• Does fork() create all processes in a UNIX system?
• What does execv() do? What is its return value?
• How to run a command in a program without getting killed?
• Does exit completely clean up a process?
• Can a parent process tell if its child process terminate normally?
• Can a child process tell if its parent process terminate normally?