Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
For the program below:
int main() {
Pid_t pid1, pid2;
Pid1 = fork();
pid2 = fork();
if (pid1 == 0) { /* child process */
thread_create(. . .);
}
if (pid2 == 0) { /* child process */
pthread_create(. . .);
}
fork();
}
a.How many unique processes are created?
b. How many unique threads are created?
Our class has been discussing this for two days. We are told that it is 2 unique threads. However when I replace the pthread_create with a print I am getting more than two. I get this output
Thread 2: 1855 0
Thread 1: 0 1859
Thread 1: 0 0
Thread 2: 0 0
Where Thread 1/2 shows the if statments and pid1 pid2 is printed.
So why is it 2? Can you provide an explanation we can show in class?
The first fork creates a second process from your first process. But the second fork is not guarded by checking the PID, so this fork happens in both processes, resulting in a total of 4 processes. The final fork at the end will then result in 8 processes.
So, when you read the if statements, you have 4 processes. Lets examine the pid values in these processes:
Process 1: Pid1=0, Pid2=0
Process 2: Pid1=0, Pid2=non-0
Process 3: Pid1=non-0, Pid2=0
Process 4: Pid1=non-0, Pid2=non-0
You will see that process 1 will now create 2 threads. Process 2 will create 1 thread, process 3 will create 1 thread, and process 4 will create no threads.
So why is it 2?
As we have seen, it is not. 4 new threads are created (for a total of 12 threads if we included the main thread of each process).
I'm not sure what a "unique" thread is supposed to be in this context, but the number of processes created here is 8; We start with one process, the first fork creates another. Both of those hit the second fork, which creates 2 more processes, and finally all of those 4 hit the last fork making for 8 processes total.
The first pthread_create is hit by the second (first child of the first) process and the child of the second process, whereas the second pthread_create is hit by the child of the second process and the second child of the first process (be very skeptical about this paragraph, I got this mixed up in my head several times so I can see why you'd struggle with this).
So depending on what exactly you're counting, there are 8 "main" threads, 4 "auxiliary" threads or 12 threads total. Not sure how you're supposed to come up with 2, other than the trivial fact that there are 2 calls to pthread_create in the source code.
If you have a very particular definition of "unique thread" that would change this, please edit your answer to include it.
You start with one process, call it PROCESS_A.
After the first fork call you have two processes, PROCESS_A (pid1 > 0) and PROCESS_B (pid1 = 0).
Both PROCESS_A and PROCESS_B then fork again, producing (in total) PROCESS_A, PROCESS_B, PROCESS_C, and PROCESS_D, so we end up with:
First fork situation:
PROCESS_A (pid1 > 0, pid2 > 0) is the parent process of B.
PROCESS_B (pid1 = 0, pid2 > 0) is a child of PROCESS_A (pid1 > 0)
Second fork situation:
PROCESS_C (pid1 > 0 (copied from A), pid2 = 0) is a child of PROCESS_A (pid2 > 0)
PROCESS_D (pid1 = 0 (copied from B), pid2 = 0) is a child of PROCESS_B (pid2 > 0).
Thus, in terms of thread creation:
PROCESS_A doesn't create either thread, because both pid1 and pid2 are non-zero in PROCESS_A.
PROCESS_B creates the first thread but not the second.
PROCESS_C creates the second thread but not the first.
PROCESS_D creates both threads.
So by my count four threads are created.
The final fork call is a red herring. A new process is created, true, but it immediately terminates as there's no code following the last fork.
Related
This is a question from one of my tasks and I'm having some confusion with it.
int main()
{
printf("line\n");
pid_t pid = fork();
fork();
fork();
if(pid == 0)
fork();
fork();
printf("line\n");
return 0;
}
How many processes would be created from the execution of the code?
From executing the code, it would generate 28 lines of output and just not sure how to find the amount of processes created in this statement.
There will be a total of 24 processes. Here is how.
After the first fork() there are two processes. In one of them pid == 0; in the other process pid != 0.
After second fork, there are 4 processes (half of them have pid == 0).
After third fork, there are 8 processes (and half of them have pid == 0).
The fourth fork statement is executed only by those processes where pid == 0. So 4 processes will execute fork (and turn into 8 processes). The other 4 processes will not execute fork and will remain 4. Alltogether we have 8+4=12 processes.
Finally, another fork turns our 12 processes into 24.
How many threads would be created from the execution of the code?
Now is the question of semantics. Do you say that processes are not threads, and so 0 threads are created? Do you say that out of 24 processes, the first one is the original process and not created by this code, so a total of 23 processes are created? This is a question of semantics, not of software, so we can't help you with this.
Number of lines printed
The first printf is executed by the original process only (since it has not forked yet). The second printf is executed by all 24 processes (just before each process terminates). So a total of 25 lines is printed.
As above, 24 leaves produce.So 24 processes produce finally.And before your first fork, "line" will be printed one time. After you fork, because of 24 processes, 24 "line" will be printed. So you will have 25 "line".
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
For(i=0, i<3, i++){
Fork()
}
Hello, this Code creates 5 process.
How can i create only 3 processes ?
Or how do i create only Child processes ?
Thank you
When you create a fork, both the parent and the newly created child process continue from the point of forking. So, if you have a loop running three times with fork, the parent creates three children, the first child creates two children, and so on. So, your example will result in more than five processes.
When a fork is created, you can record the pid (process ID). In the child process, the pid value of itself will be 0, while the parent process will have the child's pid stored. You can use this to control subsequent forks.
To create three processes, you can use:
pid_t pid;
pid = fork();
// this will be true only in the child process
// so, only the child creates another process, resulting in a total of
// three processes
if (pid == 0) {
fork();
}
After the first call to fork(), both the parent and the child process are executing the for-loop, so both of them execute the second call to fork, and now you have more processes than you wanted. To fix this you need to make the child do something different than the parent. You can tell which process is which by looking at the return value of fork; it returns 0 in the child and a nonzero value in the parent. So, something like this:
fflush(0); // not directly relevant but always a good idea before forking
for (int i = 0; i < 3; i++) {
if (fork() == 0) {
_exit(main_for_child(i)); // very important to use _exit, not exit
}
// control reaches this point only in the parent
}
#include<iostream>
#include<unistd.h>
#include<stdio.h>
using namespace std;
int main()
{
fork();
fork();
fork();
fork();
printf("*"); /*This prints 16 stars*/
return 0;
}
When working with fork(), why does it print 16 *'s?
I understand that fork() generates a new
child process that both execute the same process which would explain why one fork generates 2 stars but, with four forks it prints 16 which I can see that it doubles with each fork().
But I am not understanding why. Is each fork executing the functions and parameters below it?
Because the first fork will split into two process, the second fork() call will be called by those two processes, splitting those two processes into 4. This will continue until all the fork() calls have been called in each process. So you end up having 2^4 = 16 calls to printf("*")
In the "diagram" each bar represents the number of processes that are executing when the function is called. So the function is executed as many times as there are bars.
| fork() // The first processes creates a second (2 total)
| fork() | // Those 2 processes start 2 more (4 total)
|| fork() || // Those 4 processes start 4 more (8 total)
|||| fork() |||| // Those 8 processes start 8 more (16 total)
|||||||| printf() |||||||| // resulting in 16 calls to printf()
Is each fork executing the functions and parameters below it?
Yes, as you can see from the diagram, when a process forks the created process (and the one that created it) continues execution on the next instruction after the fork.
When you call fork(), it create a new process. You duplicate your application, and then the 2 applications continues to run and execute new instructions after the fork() call
printf("i'm the main thread\n");
fork();
printf("i'm executed 2 times\n");
fork(); //this fork is so executed 2 times, so 2 new processes, so 4 processes for all
printf("i'm excecuted 4 times\n");
fork(); //this fork is executed 4 times to ! So you have now 8 processes;
// and etc ..
fork(); //this fork is executed 8 times, 16 process now !
printf("*"); // executed 16 times
The new processes share all memory before the fork(), old changed states are for the current thread.
if you want to do anothers things depending the process :
pid_t p;
int i = 1;
p = fork();
if(p == 0)
{
printf("I'm the child\n");
i = 2;
exit(0); //end the child process
}
printf("i'm the main process\n");
printf("%d\n", i); //print 1
I believe that this creates 24 processes; however, I need verification. These questions often stump me. Thanks for the help!
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
pid_t pid = fork();
pid = fork();
pid = fork();
if (pid == 0)
{
fork();
}
fork();
return 0;
}
It's fairly easy to reason through this. The fork call creates an additional process every time that it's executed. The call returns 0 in the new (child) process and the process id of the child (not zero) in the original (parent) process.
pid_t pid = fork(); // fork #1
pid = fork(); // fork #2
pid = fork(); // fork #3
if (pid == 0)
{
fork(); // fork #4
}
fork(); // fork #5
Fork #1 creates an additional processes. You now have two processes.
Fork #2 is executed by two processes, creating two processes, for a total of four.
Fork #3 is executed by four processes, creating four processes, for a total of eight. Half of those have pid==0 and half have pid != 0
Fork #4 is executed by half of the processes created by fork #3 (so, four of them). This creates four additional processes. You now have twelve processes.
Fork #5 is executed by all twelve of the remaining processes, creating twelve more processes; you now have twenty-four.
Calculate in this way :
Start with 1(Main Process) and for every fork make it twice if fork is not inside if(pid == 0) else add 1/2 of current process to current number of process.
In your code:
1P
Got #1 fork() so double up current number of processes. Now new number of process 2P
Got #2 fork() so double up current number of processes. Now new number of process 4P
Got #3 fork() so double up current number of processes. Now new number of process 8P
Got #4 fork() but wait it's in if condition so (8+4 = 12)P
Got #5 fork() so double up the current number of processes. Now new number of process 24P
You are correct. It's 24. Just compiled and ran it w/printf before the final return statement. Got 24 lines of output.
This statement have 24+ child process.
Each invocation of fork() results in two processes, the child and the parent. Thus the first fork results in two processes. The second fork() is reached by those two processes, yielding four processes. The final fork() is reached by those four, netting eight processes more. All but one of these processes (the original) is a child of at least one of the forks.
What's the right way to tell a specific process to sleep?
I don't fully understand how to control the different processes I create..
I'm trying to make two processes that sleep for 2 and 3 seconds. When process 1 has slept for 2 seconds, and process 2 is still sleeping I want process 3 to start sleeping. But how do I tell a process to sleep? Or don't I?
int main(void)
{
pid_t p1 = fork();
pid_t p2 = fork();
pid_t p3 = fork();
//make p1 sleep(2) and p2 sleep(3)
waitpid(p1, NULL, 0); //waiting for p1 to terminate
//make p3 sleep(2);
}
As you can see I don't understand how to handle processes, or what they really are. I kind of see them as objects, but I'm guessing that's wrong.. I've tried reading some stuff about it, but they are all over 9000 pages PDF's.. A simple explanation of what I should see them as would be appreciated. And yes, this is school-material, but no, it's not an assignment.
Start with man fork which is slightly shorter than 9000 pages. The main thing is that successful fork returns two times: it returns 0 to the child process and the child's PID to the parent process. It's typically used like this:
pid_t pid = fork();
if (pid<0) { /* error while forking */
};
if (!pid) { /* code for child */
play();
whine();
sleep();
exit(0);
} else { /* code for parent */
grunt();
waitpid(...);
}
You don't normally tell the child process to do this and that, you just add code doing it to the appropriate if branch.
In your example, if all forks are successful, you end up with 8 processes:
First fork creates a new process, p1 gets 0 in the new process and some pid in the parent.
Second fork is called both in the original parent and in the child, adding 2 processes to the picture.
p2 gets 0 in all "grandchildren" and two different pids in 2 processes existing before step 2.
Third fork is called in four different processes, adding four other processes to the picture.
You could send it a SIGSTOP and then a SIGCONT I think.
kill(p1, SIGSTOP);
Alternatively and more sanely, since you're only forking and thus have complete controll over the code, you could handle the paths:
if (in_child_1)
sleep(..);
As a side note, in your code more processes are created than you expect. The thing is once p1 is created it starts executing from that point, in parallel with its parent. And so on.