Consider the code:
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
/* main --- do the work */
int main(int argc, char **argv)
{
pid_t child;
if ((child = fork()) < 0) {
fprintf(stderr, "%s: fork of child failed: %s\n",
argv[0], strerror(errno));
exit(1);
} else if (child == 0) {
// do something in child
}
} else {
// do something in parent
}
}
My question is from where does in the code the child process starts executing, i.e. which line is executed first??
If it executes the whole code, it will also create its own child process and thing will go on happening continuously which does not happen for sure!!!
If it starts after the fork() command, how does it goes in if statement at first??
It starts the execution of the child in the return of the fork function. Not in the start of the code. The fork returns the pid of the child in the parent process, and return 0 in the child process.
When you execute a fork() the thread is duplicated into memory.
So what effectively happens is that you will have two threads that executes the snippet you posted but their fork() return values will be different.
For the child thread fork() will return 0, so the other branch of the if won't be executed, same thing happens for the father thread.
When fork() is called the operating system assigns a new address space to the new thread that is going to spawn, then starts it, they will both share the same code segment but since the return value will be different they'll execute different parts of the code (if correctly split, like in your example)
The child starts by executing the next instruction (not line) after fork. So in your case it is the assignment of the fork's return value to the child variable.
Well, if i understand your question correctly, i can say to you that your code will run as a process already.When you run a code,it is already a process , so that this process goes if statement anyway. After fork(), you will have another process(child process).
In Unix, a process can create another process, that's why that happens.
Code execution in a child process starts from the next instruction following the fork() system call.
fork() system call just creates a seperate address space for the child process therefore it is a cloned copy of the parent process and the child process has all the memory elements of it's parent's process.
Thus, after spawning a child process through fork(), both processes (the parent process and the child process) resumes the execution right from the next instruction following the fork() system call.
Related
The task is as follows
Write a program that would run another process in memory and leave it running in an infinite loop. When the program is restarted, it must remove the previously started process from memory (you can use kill).
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <spawn.h>
#include <sys/wait.h>
int main(void){
int pid = getpid(); // we find out the PID of the current process and store it in a variable
FILE *file = fopen("example.txt", "r"); // getting information from a file about a child process
int filePid = 0;
fscanf(file, "%d", filePid);
fclose(file);
switch (filePid){
case -1:{ // if there is no child process, then run it and write the PID to a file
filePid = fork();
file = fopen("example.txt", "w");
fprintf(file, "%d", filePid);
fclose(file);
break;
}
case 0:{ // if this process is a child, then we go into an infinite loop
for(;;){
sleep(7); // waiting for seven seconds so that the system is not heavily loaded
}
break;
}
default:{ // if this program is started again with a child process, then we send a signal to the child process
kill(filePid, SIGKILL); // we send a signal to the child process so that it ends, and after that we write the information to the file
file = fopen("example.txt", "w"); // we write information to the file that the child process is missing
fprintf(file, "%d", -1);
fclose(file);
}
}
return EXIT_SUCCESS;
}
/Yes, I have to do it through the qnx operating system./
the errors are as follows..I'm a little confused with getpid, because I haven't used the pid variable anywhere.
and another mistake.
I will be grateful for your help.since I'm a little confused...
UPD:
I can't get the value 0
UPD: how could it execute both cases, i mean "if" and "else" blocks at the same time?
how could it execute both cases, i mean "if" and "else" blocks at the same time?
You have to have a clear understanding of how fork works, when you use fork two identical processes are created parent and child and they run simultaneously, when you say filePid = fork() and if the operation is successful then the parent process will hold the process id of the child process and child process will hold 0. So here in parent process filePid == child process ID and in child process filePid == 0.
See man fork
On success, the PID of the child process is returned in the parent,
and 0 is returned in the child. On failure, -1 is returned in the
parent, no child process is created, and errno is set appropriately.
So whatever you put in the if (filePid == 0) block will be executed by the child process and whatever you put in the else block will be executed by the parent process simultaneously.
This will be helpful if you want to know more about fork.
fork() system call creates a child process and return its pid so once child is created you have two process running same instruction after fork() one is checking pid is greater which means its parent which gets child pid and in child context OS will set the pid value to 0 so it will enter condition block intended for child
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main ()
{
int i = 3;
int pid;
while(i > 0) {
pid = fork();
if(pid > 0) {
exit(0);
} else {
i--;
}
}
}
How many process are created on that program??? I am still confused with the fork() system calls, can anybody help me to explain this?
What does fork() do?
fork() is an interesting call. You can think of it as cloning the state of your program into two exact copies -- the only difference between them will be the return value of fork(). The process that did the fork() receives the process id (pid) of the new process, while the new process receives 0.
With that in mind:
How many processes are created?
Each time you fork, you create a new process and exit the parent. You do this three times, therefore -- three processes are created by forking. This doesn't include the one that you started by starting the process, of course. :)
during start of you program, system creates 1 process (+1)
i=3, program creates new process (+1), parent exits, child continue
i=2, program creates new process (+1), parent exits, child continue
i=1, program creates new process (+1), parent exits, child continue
i=0, program exit
so, totally - 4 processes, 3 created by program, 1 by system
I have read that system function make use of execl, fork and wait functions internally. So, I tried to simulate working of system without using it. But I am not able to achieve the same working.
When we call a program using system function the code below(after) system() function call also executes. So to simulate system function i wrote this code below:
int main()
{
printf("In controller Start: %d\n\n",getpid());
system("./prog1");
printf("Forking New Process %d\n\n",fork());
printf("Process Id: %d\n\n",getpid());
execl("./infinite",0);
printf("In controller End\n\n");
return 0;
}
In the above code after running "infinite" program the last line does not get printed.
i.e. printf("In controller End\n\n");
What to do in order to print the last line and also execute the "infinite" program without using system function.
It would be great if someone can explain the step by step working of system function like which function is called by system first and so on.
Why execution is not continuing to last line like it must have did if we made a simple function call other than execl.
Foot notes:-
infinite: is a binary file created using C code.
The last line doesn't get printed because it is never executed. The execl function never returns if everything went okay, instead it replaces your program with the one in the call.
I highly recommend you read the manual pages for fork and execl.
In short, fork splits the current process into two, and returns differently depending on if it returns to the parent or the child process. In the child process you then does your exec call, while the parent process continues to do what it wants. The parent must however wait on the child process to finish, or the child process will become what is called a "zombie" process.
In your code, both the parent and the child processes calls exec.
this is basis of fork
/*previous code*/
if((cpid=fork())<0){
printf("\n\tFORK ERROR");
exit(1);
}
if(cpid==0){ /*SON*/
/*CODE FOR SON-your `execl("./infinite",0);` goes here*/
}else{ /*FATHER*/
/*CODE FOR FATHER-your `printf("In controller End\n\n");` */
}
dont forget that when making a fork memory and variables are copied to the SON pid
In your example you do the same thing in both the parent and the child process. You have to check the return value of fork, which indicates if you are in the parent or the child, and then exec in the child, while you wait in your main process.
When you call fork(), both the parent and child process continue executing the same code from that point, but the return value of fork() is different for each. Generally you would do some conditional logic based on that return value.
I would imagine that system() does something like this:
int childpid = fork();
if (childpid) {
/* This is the parent */
wait( childpid );
} else {
/* This is the child */
execl( program_name );
}
Since execl() replaces the current executable with a new one, the child will run that executable then end. The parent will wait for the child to complete then continue.
You are not performing any kind of conditional statement based on the return value of fork. If you don't make sure that one process does the exec and one does something else then both will do the same thing.
You usually want to check against 0 and then execute the program you want to run. 0 signals that everything went ok and you are in the child process.
int main()
{
int pid;
printf("In controller Start: %d\n\n",getpid());
system("./prog1");
pid = fork();
printf("Forking New Process %d\n\n",pid);
printf("Process Id: %d\n\n",getpid());
if (pid == 0) { /* Son process : execute the command */
execl("./infinite",0);
} else { /* Original process : keep working */
printf("In controller End\n\n");
return 0;
}
}
I have been asked this question for homework, and am having trouble figuring it out. If anyone can help me i would really appreciate it.
What Linux library function is like a fork(), but the parent process is terminated?
I'm fairly certain that whoever assigned you this homework is looking for the exec() family of functions, from the POSIX API header <unistd.h>, because there is nothing else that more closely resembles the sort of functionality you describe.
The exec() family of functions executes a new process and replaces the currently running process address space with the newly executed process.
From the man page:
The exec() family of functions replaces the current process image with
a new process image.
It's not exactly the same as "terminating" the parent process, but in practice it results in a similar situation where the parent process address space is erased (replaced) with the address space of the child process.
What Linux library function is like a fork(), but the parent process
is terminated?
The parent process should not terminate because , it must wait for the child processes to finish executing , after which they will be in a state called "zombie state", now it is the responsibility of the parent to clean up the leftovers of the child process. The parent process can terminate without cleaning up the child processes, but then, it is not a proper way to do it, as the exit status of the child processes should be collected and checked by the parent process.
Here is an example, to demonstrate , what i just said...
#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
int main()
{
pid_t cpid = 1 ;
int status;
cpid = fork();
// Load a application to the child using execl() , and finish the job
printf("Parent waiting for child to terminate\n");
int wait_stat = waitpid(-1,&status,0); // Parent will hang here till all child processes finish executing..
if (wait_stat < 0)
{
perror("waitpid error");
exit(-1);
}
// WIFEXITED and WEXITSTATUS are macros to get exit status information, of the child process
if (WIFEXITED (status))
{
printf("Child of id %u cleaned up\n",wait_stat);
printf("Exit status of application = %u\n",WEXITSTATUS(status));
}
}
I'm new to c language and Linux. I have a problem related to fork(),getpid()and exec()function.
I wrote a c program using fork() call the code of my program is following"
code:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
void fun()
{
printf("\n this is trial for child process");
}
int main (int argc, char const *argv[])
{
int i,status,pid,t;
if(pid=fork()<0)
{
printf("\nfailed to create the process\n");
}
if(pid=fork()==0)
{
printf("\n the child process is created");
fun();
exit(1);
}
while(wait(&status)!=pid);
return 0;
}
The out put of this program is following:
the child process is created
this is trial for child process
the child process is created
this is trial for child process
Now my questions are as follows:
Why the output of program showing same thing twice? The output supposed to be "child process is created this is trial for child process"
Why the output is not according to code ?
Can we have a program which has 4 processes and all the processes perform different task for example one process print "my name". One process print "my age", the other process print "my address ?
How to make multiple process in main function ?
How to control the execution of multiple process ?
what does the exec() function do? Can anyone please explain me the working of exec(), fork(), getpid() with a source code?
Please help this novice fellow.
Your code calls fork() multiple times:
if(pid=fork()<0) /* calls fork() */
{
...
}
if(pid=fork()==0) /* also calls fork() */
{
...
}
Each successful fork() creates a new child process. To make matters worse, the second fork() is called by both the parent and the first child.
If you're trying to create a single child process, you should call fork() just once:
pid_t pid; /* note the correct return type of fork() */
...
pid = fork();
if (pid < 0)
{
...
}
else if (pid == 0)
{
...
}
If you want to create multiple child processes, you can have the parent process call fork() in a loop.
As to questions like "what does exec do?", my advice is to learn how to use man and then come back with specific questions if there's something in the manpages that remains unclear.
In this code you are creating Three process not including your main process.
pid=fork()
is itself a statement , which forks a new process even though it is inside an if statement condition. After the first fork() call the remaining codes will be executed twice. so next fork call will be called twice. You have already created a new process.
fork returns zero to itself and its
process id to its parent
That is consider a process A forks B (not from your code)
pid = fork();
printf("pid is : %d",pid);
printf statement executes twice(one for A and one for B). For A it prints(A is parent)
pid is : 512 //some integer value
process id
and B prints
pid is : 0
So in your question
if(pid=fork()==0)
{
printf("\n the child process is created");
fun();
exit(1);
}
this is the second fork which is already executing twice. So each of this execution creates a new child process. For both childs pid value is 0. So your print statement executes, which is what you see in the output. But for both parents a pid value will be there and your if condition fails, so it wont print. These two childs are your second and third processes..So in short you create 3 processes along with the main process
The output is generated twice because you are forking twice:
if(pid=fork()<0) // Fork #1
{
printf("\nfailed to create the process\n");
}
if(pid=fork()==0) // Fork #2