Does if(fork()) create a child process? [closed] - c

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 4 years ago.
Improve this question
I'm revising for an operating systems exam and currently trying to understand this processes question:
int main()
{
int v=0;
if(fork())
{
v++;
if(!fork())
{
fork();
v--;
}
}
}
So the question asks to
Draw a tree reflecting the parent-child hierarchy of processes created when the program above is run.
How many separate copies of the integer variable v are created? Discuss what is the value of v at the end of the program for each of the processes in the tree.
The main thing I'm having an issue with is the
if(fork())
line in the code. From looking at other stack overflows I realised that
if(fork()) = if(fork() != 0)
but I'm still having difficulty understanding whether the first if statement creates a child process? Because thats the only way that the second if statement:
(!fork())
can be executed?
This is how far I've got with my current understanding of the question.
screenshot of attempt
Hopefully the diagram is legible! I'd be really grateful for any hints or pointers with this.

Notice that if (fork()) /*etc*/ is exactly the same as
pid_t newtmp = fork();
if (newtmp != 0) /*etc*/
where newtmp is a fresh (new) variable name not occurring in your program (you could use x1, x2 etc.... provided it has no occurrence in your program), and pid_t is some integral type (probably int).
Once you rewrote your code with explicit and unique names given to result of fork you'll understand it better.
BTW, the code is poor taste. When you use fork you need to handle three cases:
the fork failed (e.g. because your system has not enough memory, or because you exceeded some limits) and gives -1
the fork succeeded in the child so gives 0
the fork succeeded in the parent, so gives the pid of the child.
But when you code if (fork()) you are forgetting -or handling incorrectly- the first case (failure). It can rarely happen.
Read carefully (and several times) the fork(2) man page. Notice that fork is difficult to understand.
Regarding limits, be aware of setrlimit(2) (and the ulimit bash builtin).

The answer is
if (fork ())
may or may determine whether a child process was created.
Go to the man page:
http://man7.org/linux/man-pages/man2/fork.2.html
We find that fork () returns three types of values:
-1 => fork() failed
0 => return value in the child process
a positive value => success and the PID of the child process.
Thus the test
if (fork ())
which is the same as
if (fork () != 0)
may succeed whether or not a child process was created. A competently written question would have said
if (fork () > 0)
Assuming everything works correctly:
int main()
{
int v=0;
if(fork()) // Creates a child process that does nothing.
{
v++;
if(!fork()) // Creates a child process that creates a child process (that then does nothing but decrement v).
{
fork();
v--;
}
}
}

Related

How can the multi-core cpu run the program interleaved?

The output of the program are not obviously contents from the printf()s in teh code. Instead it looks like characters in irregular sequence. I know the reason is because the parent process and child process are running
at the same time, but in this program I only see pid=fork(), which I think means pid is only the id of child process.
So why can the parent process print?
How do the two processes run together?
// fork.c: create a new process
#include "kernel/types.h"
#include "user/user.h"
int
main()
{
int pid;
pid = fork();
printf("fork() returned %d\n", pid);
if(pid == 0){
printf("child\n");
} else {
printf("parent\n");
}
exit(0);
}
output:
ffoorrkk(()) rreettuurrnende d 0
1c9h
ilpda
rent
I focus my answer on showing how the observed output can result from the shown program. I think that it will already clear things up for you.
This is your output.
I edited it to use a good guess of what is parent (p) and child (c):
ffoorrkk(()) rreettuurrnende d 0\n
cpcpcpcpcpcpcpcpcpcpcpcpccpcpcppccc
1 c9h\n
pccpcpp
ilpda\n
ccpcpcc
rent
pppp
If you only use the chars with a "c" beneath, you get
fork() returned 0
child
If you only use the chars with a "p" beneath, you get
fork() returned 19
parent
Split that way, it should match what you know about how fork() works.
Comments already provided the actual answer to the three "?"-adorned questions in title and body of your question post.
Lundin:
It creates two processes and they are executed just as any other process, decided by the OS scheduler.
Yourself:
each time fork() is called it will return twice, the parent process will return the id of child process, and child process will return 0
Maybe for putting a more obvious point on it:
The parent process receives the child ID and also continues executing the program after the fork().
That is why the output occurs twice, similarily, interleaved, with differences in PID value and the selected if branch.
Relevant is also that in the given situation there is no line buffering. Otherwise there would be no character-by-character interleaving and everthing would be much more readable.

Create exactly 5 process with fork() [closed]

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
}

C homework with pipes and forks [closed]

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 6 years ago.
Improve this question
Hello everyone,
I'm quite lost in my school homework since they haven't told us much about it and I haven't done anything like that before.
The task is:
In the C language create a program that creates two processes (fork function) and connects them via pipe (the pipe function).
The first descendant redirects its' stdout into the pipe and writes (space separated) pairs of random numbers into it (function rand).
Delay the output of the numbers (i.e. by 1 second).
The first descendant has
to treat the SIGUSR1 signal (sigaction function) and in case of receiving such signal it prints a string “TERMINATED” to it's stderr and terminates.
The second descendant redirects the pipe output to it's stdin, redirects it's stdout into a file called out.txt in
the current directory and executes a binary file (execl function) for finding the greatest common divisor (the output of our previous tasks where we had to write a makefile that runs a small C program that detects if a number is prime).
The parent process waits 5 seconds and then sends SIGUSR1 to the first process (number generator). This should perform a correct termination of both processes. It waits for the sub-processes to terminate (wait function) and terminates itself.
In fact you are implementing something like this: while : ; do echo $RANDOM $RANDOM ; sleep 1; done | ./c1_task > out.txt
I'm absolutely lost in this and I have nothing so far unfortunatelly.
I don't know where to start.
Could somebody advise me something, please?
Thanks in advance!
Since I don't believe in doing people's work for them, I can't give you the "solution." I can, however, show you some of the concepts that you need to know to fulfill your assignment. I can also give you a couple of links, but if you just search for help with the concepts you don't understand, you're likely to find the information you need anyways.
Now that I've delivered a paragraph of introductory information, I'm going to work you through some of the concepts you need to understand to solve this problem.
I may fill in some missing information if I get (and feel like it's worth spending) the time necessary to turn this into a pseudo-tutorial. :)
The information provided may be simplified, a little vague, or otherwise open to improvement. Feel free to let me know if you, dear reader, spot a problem.
First Concept: fork()-ing
What is it? fork() makes it easy to do multiple things simultaneously by duplicating (much of) the current process into another process. (Actually, it is similar to asexual reproduction.)
For instance, the child process (this is the new process that was created by making the fork() system call) inherits open file descriptors (this is an important point!), has its own copy of variables that the parent process (has/had), etc.
Example: Here's an example program that illustrates a thing or two. Note the wait(). It makes the parent, the process that called fork(), wait to continue executing the rest of the program until a child has terminated. Without wait(NULL), we can't guarantee that the parent's printf statement will run after the child's printf statement.
#include <stdio.h> //the usual, perror
#include <stdlib.h> //exit
#include <sys/types.h> //wait() / pid_t
#include <sys/wait.h> //wait()
#include <unistd.h> // fork()
int main () {
pid_t cpid;
//create our child.
//fork() returns -1 if the fork failed, otherwise it returns
// the pid of the child to the parent,
// and 0 to the child
cpid = fork();
//Both the child process and parent process executed the
//"cpid =" assignment.
//However, they both modified their own version of cpid.
//From now on, everything is run by both the child and parent.
//the fork failed; there is no child so we're done.
if (cpid < 0) {
perror("During attempted fork");
exit(EXIT_FAILURE);
}
//Though the if statement will be checked by both,
//cpid will equal 0 only in the child process.
if (cpid == 0) {
//This will be executed by the child.
printf("Hello. I'm your child.\n");
//Now that we've let Pops know that we're alive...
exit(EXIT_SUCCESS);
}
else if (cpid > 0) {
//wait for our child to terminate.
//I dare you to comment this out & run the program a few times.
//Does the parent ever print before the child?
wait(NULL);
printf("I proudly parented 1 child.\n");
}
return 0;
}
Other: You can see another example here.
Second concept: Pipes
What is a pipe? A pipe is a method for interprocess communication. Basically, it has one end that data can be put in (write() is one way to do it) and one end that data can be gotten out of (using read).
Pipes are created using the pipe() system call. It returns -1 on error. It's only argument is the address of an array of two ints, which we'll call pipe_fds.
If the call succeeded, the first element in pipe_fds contains the file descriptor that is used to read from the pipe; the second element contains the file descriptor used to write to the pipe.
You can write to the pipe with write() and read from the pipe with read(). (More info about using pipes can be found at various places on the internet.
Here's an example:
#include <stdio.h> //the usual, perror
#include <stdlib.h> //exit
#include <sys/types.h> //wait() / pid_t
#include <sys/wait.h> //wait()
#include <unistd.h> // fork(), pipe()
#define BUFLEN 256 //must be greater than one
int main () {
int pipe_fds[2],
pipe_ret;
pid_t cpid;
//Let's create a pipe.
//Note that we do this *before* forking so that our forked child
// has access to the pipe's file descriptors, pipe_fds.
pipe_ret = pipe(pipe_fds);
//we couldn't create our pipe
if (pipe_ret == -1) {
perror("Pipe Creation");
exit(EXIT_FAILURE);
}
//create our child.
cpid = fork();
//the fork failed; there is no child so we're done.
if (cpid < 0) {
perror("During attempted fork");
exit(EXIT_FAILURE);
}
//Am I the child?
if (cpid == 0) {
//close the childs read end of the pipe.
//Failing to close unused pipe ends is life or death!
//(Check `man 7 pipe`)
close(pipe_fds[0]);
//Send a message through the pipe.
//NOTE: For simplicity's sake, we assume that our printing works.
// In the real world, it might not write everything, etc.
//We could use `write()`, but this way is easier.
dprintf(pipe_fds[1], "Daddy, I'm alive.\n");
//We're done writing. Close write end of the pipe.
//This is the wise thing to do, but it would get closed anyways.
close(pipe_fds[1]);
//Now that we've let Pops know that we're alive...
exit(EXIT_SUCCESS);
}
else if (cpid > 0) {
char buf[BUFLEN] = {};
int bytes_read = 0;
//close *our* write end of the pipe. Important!
//Comment this out and watch your program hang.
//Again, check out `man 7 pipe`.
close(pipe_fds[1]);
//read data from pipe until we reach EOF
while ((bytes_read = read(pipe_fds[0], buf, BUFLEN - 1)) > 0) {
//null terminate our string.
//(We could use snprintf instead...)
buf[bytes_read] = '\0';
//You can comment this out to prove to yourself that
//we're the one printing the child's message.
printf("%s", buf);
}
//close read end of pipe
close(pipe_fds[0]);
//wait for our child to terminate.
wait(NULL);
printf("I proudly parented 1 child.\n");
}
return 0;
}
As you can see, I just gave a small tutorial on two of the concepts you need to know to finish your assignment. I need some sleep, so I'll leave it at that for tonight.
Read and experiment with the examples! Notes in the comments are to help you learn.

Why isn't this if statement working? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I'm forking, and executing a certain block in the child process. My problem is that my child process never gets into the if statement. Why is this?
if((x = strcmp(subargs[next_redirect], ">")) == 0)
{
pid = fork();
fprintf(stderr, "my PID is %i\n", pid);
if(pid == 0)
{
fprintf(stderr, "the name of our file is %s\n", subargs[i+1]);
fp = creat(subargs[i+1], S_IWUSR | S_IRUSR);
dup2(fp, STDOUT_FILENO);
close(fp);
//create sub-command
makesubcommand(subcommand, subargs, last_redirect + 1, i);
execvp(subcommand[0], subcommand);
}
last_redirect = i;
next_redirect = getnextredirect(subargs, i+2, subargc);
}
My output is
my PID is 11080
my PID is 0
When you fork, the child process receives a PID of 0, correct?
My problem is at if(pid == 0){}. The code in that block never executes.
Your child process is not getting to if because of wait() system call.
The system call wait() blocks the calling process until one of its child processes exits or a signal is received.wait() takes the address of an integer variable and returns the process ID of the completed process. Some flags that indicate the completion status of the child process are passed back with the integer pointer. One of the main purposes of wait() is to wait for completion of child processes.
The execution of wait() could have two possible situations.
If there are at least one child processes running when the call to wait() is made, the caller will be blocked until one of its child processes exits. At that moment, the caller resumes its execution.
If there is no child process running when the call to wait() is made, then this wait() has no effect at all. That is, it is as if no wait() is there.
So remove the wait() system call. and your program will run ok.
Check the call of execvp in your code, which may have errors. You can check the return value of wait to get the child pid or -1.
Apologies. It turns out that my problem was
fprintf(stderr, "the name of our file is %s\n", subargs[i+1]);
I was left thinking that the block was never executed because this wouldn't print anything.
it turns out that there is a problem with subargs.
I appreciate all the help.

working of fork in c language [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
Now I have a problem in understanding the working of fork() system call.
I write a code which is following :
#include<stdio.h>
int main()
{
int a, b;
b=fork();
printf("\n the value of b = %d",b);
}
The output of this code is following :
Now I don't understand why the output is like this ?
After that i just add a line to my code and output is completely different.
my code is following:
int main()
{
int a, b;
b=fork();
When i run the code the output is following
2389my name is manish
the value of b = 0
Now I'm totally confused about the working of fork() call.
My question are following:
How fork() works?
Where the control goes after the fork() call?
Can any body explain why the outputs of codes written in problem?
Why the output of b occurring at different places means in first code
the output of b = 2260 is just before the output b = 0 while the value of b = 2389 is not just before the b = 0?
Please explain me the working of fork in the code written in the problem so that I can learn it properly .
It might help to first understand why the word fork was used to name this function. Ever heard of a "fork on the road?" At a fork, the process has to split paths.
First there is a single process executing normally until you reach the fork call. When fork is called, a new process is created, which is identical in virtually every way as the original process, except for the return value of the fork function. The newly created process is called the child process, and hence the process that spawned it is referred to as the parent process.
Since you'd want to perform different tasks for each branch of the fork, it necessitates that you be able to distinguish the child process from the parent process. That's where the return value of fork comes in: fork returns the process id (pid) of the child (the newly created process) to the parent; it returns 0 to the child. Also, should the execution of fork go wrong, the return value is -1.
In your code, you don't distinguish between the child and parent process, so both processes run the entire code that follows after the fork call.
//what the child process looks like after fork is called
int main()
{
int a, b;
b=fork(); // <-- current line of execution: 0 is returned to b
printf("\nmy name is manish\n");
printf("\n my name is anil\n");
printf("\n the value of b = %d",b);
}
// what the parent process looks like after fork is called
int main()
{
int a, b;
b=fork(); // <-- current line: child process id is returned
printf("\nmy name is manish\n");
printf("\n my name is anil\n");
printf("\n the value of b = %d",b);
}
As you can see, both processes have the same code following the fork, hence the output is repeated. Perhaps if you want the parent process to output Manish and the child to output Anil, then you can do something like:
int main()
{
pid_t b; // note that the actual return type of fork is
// pid_t, though it's probably just an int typedef'd or macro'd
b = fork();
if (b == -1) perror("Fork failed");
else if (b > 0) {
printf("My name is Manish\n"); // parent process
else
printf("My name is Anil\n"); // child process
printf("The value of b is %d\n", b);
return 0;
}
Finally, the last comment that must be made is that in your code, the output appears to have been executed first by one process in its entirety and then the other process in its entirety. That may not always be the case. For example, the operating system might allow the parent to execute the 'manish' output, then make this process wait, and handing the cpu over to the child process, which then executes 'manish'. However, the child process may continue and execute 'anil' and 'b' outputs, completing execution of the child process and thus returning execution back to the parent process. Now the parent finishes its execution by outputting 'anil' and 'b' itself. The final output of running this program may look something like:
my name is manish // executed by parent
my name is anil // child
the value of b = 0 // child
my name is anil // parent
the value of b = 2244 // parent
manish.yadav#ws40-man-lin:~$
Take a look at the man page for fork.
Also look at waitpid for proper handling of child processes by parent processes so you don't create zombies.
Edit: In response to your questions in the comments, I'll answer how you can simply run each process consecutively.
int main()
{
pid_t pid;
int i;
for (i=0; i<NUM_PROCESSES; i++)
{
pid = fork();
if (pid == -1)
{
perror("Error forking");
return -1;
}
else if (pid > 0)
{
// parent process
waitpid(-1, NULL, 0); //might want to look at man page for this
// it will wait until the child process is done
}
else
{
// do whatever each process needs to do;
// then exit()
doProcess(i);
exit(0);
}
}
// do anything else the parent process needs to do
return 0;
}
Of course, isn't the best code, but it's just to illustrate the point. The big idea here is the waitpid call, which causes the parent process to wait until the child process it just forked to terminate. After the child prcoess completes, the parent continues after the waitpid call, starting another iteration of the for loop and forking another (the next) process. This continues until all child process have executed sequentially and execution finally returns to the parent.
Fork creates a copy of your current process.
Both the original and the copy continue executing from the point at which fork() was called.
Because your code is executed twice, your print statements are also evaluated twice. In the copied process, the value of b is 0. In the original process, the value of b is the process ID of the copied process.
Once your processes start running concurrently, they will be scheduled independently by your operating system and thus you have no guarantees about when they will actually be run.
Forking is implemented by the OS. It basically creates a child process and starts running it after the fork().
The parent process receives the process id of the file process: b=fork(); b has the process id. The child process get a pid of zero.
(and 4) Because both process can either run in parallel or be time sliced, your output will vary.
You may want to check this out: http://en.wikipedia.org/wiki/Fork_(operating_system)
You'd better start from this.
Here you find explanation and code example.

Resources