Assuming that the system call fork () never fails, consider the following C programs P1 and P2 executed on a UNIX / Linux system: /*P1*/ Int main() { fork (): fork () ; fork () ; Printf(“Happy\n”); } /*P2*/ Int main() { fork (); Printf(“Happy\n”); fork () Printf(“Happy\n”); fork () ; Printf(“Happy\n”); } Statement I: P1 displays "Happy" 8 times. Statement II: P2 displays "Happy" 12 times. In the light of the above statements, choose the correct answer from the options given below
Statement I is correct but Statement II is false
This question asks us to analyze the output of two C programs, P1 and P2, which use the fork() system call in a UNIX/Linux environment. The fork() system call is fundamental for process creation.
The fork() system call creates a new process, called the child process, which is an almost exact copy of the calling process (the parent process). After the fork() call, both the parent and child processes execute the code starting from the statement immediately following the fork() call. The key difference is the return value of fork():
Each time a process executes a fork(), the number of processes doubles at that point in the code, as both the original process and the newly created child process continue execution.
Program P1 has three consecutive fork() calls followed by a Printf("Happy\n") statement. Let's trace the number of processes executing the code:
All 8 processes that exist after the third fork() will execute the statement Printf("Happy\n").
The number of processes at each stage can be represented as powers of 2:
| Stage | Number of Processes |
|---|---|
| Initial | $2^0 = 1$ |
| After 1st fork() | $2^1 = 2$ |
| After 2nd fork() | $2^2 = 4$ |
| After 3rd fork() | $2^3 = 8$ |
Since the Printf is the last statement and is executed by all 8 processes that reach that point, "Happy" will be displayed 8 times.
Statement I says P1 displays "Happy" 8 times. Based on our analysis, this statement is true.
Program P2 has `fork()` and Printf() calls interleaved. Let's trace the execution path and the number of prints at each Printf() call.
The total number of times "Happy" is displayed is the sum of prints from each Printf() statement:
Total prints = (Prints from 1st Printf) + (Prints from 2nd Printf) + (Prints from 3rd Printf)
Total prints = $2 + 4 + 8 = 14$.
| Statement | Number of Processes Reaching Statement | Number of Prints |
|---|---|---|
| fork() (1st) | 1 | - |
| Printf("Happy\n") (1st) | 2 | 2 |
| fork() (2nd) | 2 | - |
| Printf("Happy\n") (2nd) | 4 | 4 |
| fork() (3rd) | 4 | - |
| Printf("Happy\n") (3rd) | 8 | 8 |
So, program P2 displays "Happy" 14 times.
Statement II says P2 displays "Happy" 12 times. Based on our analysis, this statement is false.
Therefore, Statement I is correct, but Statement II is false.
| Program | fork()/Printf() Sequence | Number of Processes Executing Printf() | Total Prints |
|---|---|---|---|
| P1 | fork() fork() fork() Printf() |
$2^3 = 8$ processes reach the single Printf() | 8 |
| P2 | fork() Printf() (1st) fork() Printf() (2nd) fork() Printf() (3rd) |
2 processes reach 1st Printf() 4 processes reach 2nd Printf() 8 processes reach 3rd Printf() |
$2 + 4 + 8 = 14$ |
The fork() system call is a powerful mechanism in Unix-like operating systems for creating new processes. Each successful fork() call essentially duplicates the calling process. The child process inherits many attributes from the parent, including the code segment, data segment, environment variables, open file descriptors, etc. However, they are distinct processes with their own memory space (usually achieved through copy-on-write) and their own unique Process ID (PID). Understanding how code execution diverges in parent and child processes after a fork() is crucial for analyzing programs like P1 and P2, especially when input/output operations like Printf() are involved, as each process's output contributes to the overall display.
A computer system has 7 tape drives. There are ‘n’ processes competing for them. Each process may need 2 tape drives. What is the maximum value of ‘n’ for which the system is guaranteed to be deadlock free?
Identify the circumstances under which pre-emptive CPU scheduling is used:
(a) A process switches from Running state to Ready state
(b) A process switches from Waiting state to Ready state
(c) A process completes its execution
(d) A process switches from Ready to Waiting state
Choose the correct option:
Match List I with List II
List I | List II | ||
System calls | Description | ||
A. | fork() | I. | Sends a signal from one process to another process |
B. | exec() | II. | Indicates termination of the current process |
C. | kill() | III. | Loads the specified program in the memory |
D. | exit() | IV. | Creates a child process |
Choose the correct answer from the options given below :
________ system call creates new process in Unix.
The processes that are residing in main memory and are ready and waiting to be executed, are kept on a list called