1)Including the initial parent process, how many processes are created by the pr
ID: 669339 • Letter: 1
Question
1)Including the initial parent process, how many processes are created by the program shown in Figure 3.31?
#include <stdio.h>
#include <unistd.h>
int main()
{
/* fork a child process */
fork();
/* fork another child process */
fork();
/* and fork another */
fork();
return 0;
}
2) The Sun UltraSPARC processor has multiple register sets. Describe what happens when a context switch occurs if the new context is already loaded into one of the register sets. What happens if the new context is in memory rather than in a register set and all the register sets are in use?
3) Explain the circumstances under which which the line of code marked printf("LINE J") in Figure 3.33 will be reached.
4) Using the program in Figure 3.34, identify the values of pid at lines A, B,
C, and D. (Assume that the actual pids of the parent and child are 2600
and 2603, respectively.)
5) Using the program shown in Figure 3.35, explain what the output will be at lines X and Y.
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#define SIZE 5
int nums[SIZE] = {0,1,2,3,4};
int main()
{
int i;
pid t pid;
pid = fork();
if (pid == 0) {
for (i = 0; i < SIZE; i++) {
nums[i] *= -i;
printf("CHILD: %d ",nums[i]); /* LINE X */
}
}
else if (pid > 0) {
wait(NULL);
for (i = 0; i < SIZE; i++)
printf("PARENT: %d ",nums[i]); /* LINE Y */
}
return 0;
}
Figure 3.35 What output will be at Line X and Line Y?
Explanation / Answer
1)Including the initial parent process, how many processes are created by the program shown in Figure 3.31?
#include <stdio.h>
#include <unistd.h>
int main()
{
1./* fork a child process */
2. fork();
3. /* fork another child process */
4. fork();
5. /* and fork another */
6. fork();
7. return 0;
}
When you call a fork() system call, a child process is created, and a copy of the same memory, register and program will be made and given away to the child process.
The possible outcome of the fork() system call is:
-1: Due to some reasons, the child process has not been created.
If the child process is created successfully, this fork() will return the positive number(Process ID) to the parent process, which called the fork(), and a 0 will be returned to the child process, which was created as a result of the fork system call.
Once the child process has been created, the same process will be executed by both the parent and the child, and the processor will continue executing the processes from an instruction right after the fork system call.
So, as per your program, there are a total of 7 lines of code to be executed within the main.
Assume the parent process ID is: 2345.
At line 2: there is a system call fork(), and assume a child process has been created with process ID: 23451.
Therefore, from here onwards, 2 processes (2345, 23451)are being executed in parallel (if not, pseudo parallelism).
Line 4 will be executed by both the processes, 2345 and 23451. Assume another process has been created by 2345 (call it 23452), and also by the process 23451 (call it 234511).
From here onwards, 4 processes (2345, 23451, 234511, 23452) are being executed in parallel.
Line 6 will be executed by all the 4 processes. Assume another process has been created by each of the process. Means 4 more processes will be created by existing 4 processes. Call them 23453(created by 2345), 234512(created by 23451), 2345111(created by 234511), 234521(created by 23452).
Finally, this shows that, including the parent process, there are 8 processes in existence by then.
2) The Sun UltraSPARC processor has multiple register sets. Describe what happens when a context switch occurs if the new context is already loaded into one of the register sets. What happens if the new context is in memory rather than in a register set and all the register sets are in use?
A very simple concept is, when the processor wants to execute another process, before it completes executing the existing process (due to preemption), a context switch will happen.
Context switch is the limited register set (like Program Counter, Accumulator and other registers) which are being used by the processor, to execute the current process, will be reused by the new process which should be executed after preemption. Later when this process comes back to running state, it has to continue executing from where it has been stopped. To achieve this, all the previous values of the registers should be stored back into their respective positions, simulating the exact state at which the process has been preempted.
This can be achieved by simple pushing the contents of the register set to the stack, so that, when the process comes back to running state, the contents of the stack will be popped back to registers. Please do note that, as the process is not completed, the memory allotted to that process will still be retained, in most of the cases, whether the process is in either running state or some other state (like ready, suspended etc…).
3) Explain the circumstances under which the line of code marked printf("LINE J") in Figure 3.33 will be reached.
As we already discussed in question 1, when fork() system call has been called, the parent process will create a child process, and the system call will return a 0 to the child process, and the positive number(child process ID to the parent).
Therefore, at line 10, a child process will be created. From there onwards, two instances of the same process will be executed by both the parent and child processes.
When the parent is being executed, at line 12, the condition will evaluate to false (if the child process has been created), and will skip that if block, and will be proceeded to line 16, which will also be evaluated to false (the fork() will return the positive number, PID to the parent), and will also skip that block, and will proceed to line 20, which is the else block and therefore will be executed.
With the child process perspective, once the fork() has created it, when the child is being executed, at line 12, the condition will evaluate to false (as the child has been created), and will skip that if block, and will be proceeded to line 16. Here this condition will evaluate to true (the fork() will return 0 to the child process), and whould execute both the lines (line 17, and line 18) in that block. But note that execlp() is a system call used to replace the process image with a new process, and usually doesn’t return back, unless some error occurs. Therefore, once the image has been replaced, which results in non-execution of the line 18. But if an error occurs for the system call execlp(), then it will further proceed executing that block(line 18).
4) Using the program in Figure 3.34, identify the values of pid at lines A, B,
C, and D. (Assume that the actual pids of the parent and child are 2600
and 2603, respectively.)
Referring to problem 1, given the PID of parent process is 2600, and that of the child is 2603.
At line 10, a child process has been created.
On successful creation of the child process. the if(pid < 0 ) block will be executed neither by the parent process, nor by the child process.
The else if(pid == 0) block will be executed by the child process with process ID 2603, and the else block will be executed by the parent.
At this point, note that getpid() is a system call which will read nothing, but will return the process ID of the process which called this system call.
Therefore the else if block will be executed by the child process(with PID = 2603), and the getpid() in that block will return the value of PID and will be stored into the variable pid1.
Therefore, at point A, pid will print a value of 0(ZERO) that’s why the condition is evaluated to true, and you entered that else if block.
At point B, pid1, is the value assigned at line 17 will be the process ID of the child. Therefore, at point B, pid1 will print a value of 2603(child process ID).
On the same lanes, at point C, pid will print a value of the child process ID(a value returned by the fork() system call to the parent process),. Therefore, at point C pid will print a value of 2603(process ID of the child).
At point D, pid1, is the value assigned at line 22 will be the process ID of the parent. Therefore, at point D, pid1 will print a value of 2600(parent process ID).
5) Using the program shown in Figure 3.35, explain what the output will be at lines X and Y.
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#define SIZE 5
int nums[SIZE] = {0,1,2,3,4};
int main()
{
1. int i;
2. pid t pid;
3. pid = fork();
4. if (pid == 0) {
5. for (i = 0; i < SIZE; i++) {
6. nums[i] *= -i;
7. printf("CHILD: %d ",nums[i]); /* LINE X */
8. }
9. }
10. else if (pid > 0) {
11. wait(NULL);
12. for (i = 0; i < SIZE; i++)
13. printf("PARENT: %d ",nums[i]); /* LINE Y */
14. }
15. return 0;
16. }
Figure 3.35 What output will be at Line X and Line Y?
As per the same logic which we discussed in problem 1, the line 4 will be evaluated to true by the child process, and the lines 5,6,7,8 will be executed by the child process. The line 10 will be evaluated to true by the parent process, and the lines 11,12,13 will be executed by the parent process.
Initially nums[5] = {0,1,2,3,4}.
The same values will be passed to the child process.
By child process:
Line 5: It indicates that the loop (line 6, and line 7) will be evaluated for 5 times, for different values of i:
i = 0: nums[0] = nums[0] * -i.
i = 1: nums[1] = nums[1] * -i.
i = 2: nums[2] = nums[2] * -i.
i = 3: nums[3] = nums[3] * -i.
i = 4: nums[4] = nums[4] * -i.
Therefore at Line X the output will be:
CHILD: 0 CHILD: -1 CHILD: -4 CHILD: -9 CHILD: -16
By parent process:
Line 10: It indicates that the loop (line 12, and line 13) will be evaluated for 5 times, after waiting the wait(NULL) system call once.
The wait() system call is used to wait for state changes in a child of the calling process, and obtain information about the child whose state has changed. That means this loop will wait till the child process finishes its execution.
After that, the loop will be evaluated, for different values of i:
i = 0: nums[0] value is 0.
i = 1: nums[1] value is 1.
i = 2: nums[2] value is 2.
i = 3: nums[3] value is 3.
i = 4: nums[4] value is 4.
Therefore at Line Y the output will be:
PARENT: 0 PARENT: 1 PARENT: 2 PARENT: 3 PARENT: 4
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.