Why am I having to terminate my program manually? - c++

I have a program that should launch another process and work simultaneously with it. I am using fork() and system() to accomplish this. I have code verifying that that my system() call returns, but every time I execute I have to manually end the execution by typing ctrl c. I can tell that one of my processes terminates, but I am not quite sure which one. I believe it is the parent. Both should be caught by return statements though.
Here is the parent process code (forkWaitTest):
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
int main(void)
{
pid_t childPID;
int status;
childPID = fork();
if(childPID >=0)
{
if(childPID == 0)
{
cout <<"I'm the fork child";
cout.flush();
status=system("child");
cout << "status = " << status;
//exit(0);
//cout << "Am I getting here?";
}
else{
cout << "I am the parent and can keep doing things ";
int y=1;
int x=7;
cout<< y+x << " ";
}
}
return 0;
}
This is the child process that is called
#include <stdio.h>
int main(int argc, char *argv[] )
{
printf("I am the child\n");
return 0;
}
Here is my output:
-bash-4.2$ forkWaitTest
I am the parent and can keep doing things 8 I'm the fork child-bash-4.2$ I am the child
status = 0

Your parent DID terminate. Let's look at your output:
-bash-4.2$ forkWaitTest
I am the parent and can keep doing things 8 I'm the fork child-bash-4.2$ I am the child
status = 0
Now let's look at that more closely, particularly this bit:
I'm the fork child-bash-4.2$
See, right in the middle, it says bash-4.2$. That's the command prompt after the parent terminates. Then the child runs and also exits, but you are confused as it prints after the bash prompt. Your ^C merely prints the next line.
To verify, press return a few times rather than ^C.

Make sure your messages end with newlines (add << endl to the outputs, for example).
I see your bash prompt (the -bash-4.2$) mixed up with the other outputs, partly because you don't have newlines in the outputs, and partly because your code doesn't show any attempt to wait for children to die. This means that your process did die.
You could type: ls -l and the shell would execute that command because it is waiting for you to type something. When you interrupt it (the shell), it prompts again, but it would have taken your input even without the interrupt.
With a slightly modified version of the child:
#include <stdio.h>
#include <unistd.h>
int main(void)
{
printf("I am the walrus (%d)\n", (int)getpid());
return 0;
}
and a slightly modified version of the parent:
#include <cstdlib>
#include <iostream>
#include <sys/wait.h>
#include <unistd.h>
using namespace std;
int main(void)
{
pid_t childPID;
int status;
childPID = fork();
if (childPID >= 0)
{
if (childPID == 0)
{
cout << "I'm the forked child (" << getpid() << ")\n";
cout.flush();
status = system("child");
cout << "status = " << status << endl;
cout << "Am I getting here?\n";
return 0;
}
else
{
cout << "I am the parent and can keep doing things ";
int y = 1;
int x = 7;
cout << y + x << endl;
}
}
int corpse;
while ((corpse = wait(&status)) != -1)
cout << "PID " << corpse << " exited with status " << status << endl;
return 0;
}
and with a prompt Osiris JL:, an example of the output I get is:
Osiris JL: ./parent
I am the parent and can keep doing things 8
I'm the forked child (3192)
I am the walrus (3193)
status = 0
Am I getting here?
PID 3192 exited with status 0
Osiris JL:
Note that the 'child' program is run by a child of the parent process's own child (that's why the getpid() values are printed). And the wait() in a loop in the parent process ensures that the child has died before the parent dies. Given the structure of the child process, which uses the system() function, the grandchild process (running the partly misnamed child process) has exited before the child exits before the parent exits. Omit the wait() loop and the parent can easily exit before the child and grandchild do:
Osiris JL: ./parent
I am the parent and can keep doing things 8
I'm the forked child (3207)
Osiris JL: I am the walrus (3208)
status = 0
Am I getting here?
ls -ld parent* child*
-rwxr-xr-x 1 jleffler staff 8784 Sep 20 15:57 child
-rw-r--r-- 1 jleffler staff 122 Sep 20 15:57 child.cpp
drwxr-xr-x 3 jleffler staff 102 Sep 20 15:57 child.dSYM
-rwxr-xr-x 1 jleffler staff 9808 Sep 20 16:02 parent
-rw-r--r-- 1 jleffler staff 858 Sep 20 16:02 parent.cpp
drwxr-xr-x 3 jleffler staff 102 Sep 20 16:02 parent.dSYM
Osiris JL:

Related

How can I resume a stopped process?

Following this documentation, I am testing how to stop and resume a process. I have basic code to test as follows:
#include <iostream>
#include <csignal>
#include <unistd.h>
int main() {
std::cout << "Hello" << std::endl;
int pid = getpid();
kill(pid, SIGSTOP);
kill(pid, SIGCONT);
std::cout << "Bye" << std::endl;
return 0;
}
The output is:
Hello
It stops the process, but it never resumes it. How should I fix it?
A solution, if a bit complicated, is to create a child process to start and stop the parent. Here is a small code example, that might help:
#include <iostream>
#include <csignal>
#include <unistd.h>
int pid; //Include declaration outside so it transfers to the child process
int main() {
std::cout << "Hello" << std::endl;
pid = getpid();
int returned_pid = fork(); //Duplicate process into 2 identical processes
if(returned_pid) {
// If it is the parent process, then fork returns the child process pid
// This is executed by the parent process
usleep(1000); // Sleep a millisecond to allow for the stop command to run
} else {
// If fork returns 0, then it is the child process
// The else is executed by the child process
kill(pid, SIGSTOP); // Stop parent process
usleep(3000000); // Delay 3 seconds
kill(pid, SIGCONT); // Resume parent process
}
if(returned_pid) { // Only print if parent process
std::cout << "Bye" << std::endl;
}
return 0;
}
Clarification: The fork command returns 2 different values in the 2 processes: 0 in the child, and the pid of the child process in the parent.
Other note: When running this in a terminal, it will look weird, as the terminal may note that the process was stopped and give a new command line, but then the process resumes, so prints Bye over it. Just a note.

Child process becomes Defunct after fork and exec

I am learning fork and exec and creating multiple child processes using fork and execlp and all I do in the child process is let it sleep. Basically I just want all my child to be alive. But as soon as i start my monitor.cpp which creates processes all of the child exit immediately and they do defunct!
Monitor which forks multiple children
#include <iostream>
#include <thread>
#include <chrono>
#include <string>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char* argv[])
{
for(size_t i=0; i<std::stoi(argv[1]) ; ++i)
{
int pid = fork();
if(pid == 0)
{
execlp("child", "child", std::string(std::to_string(i)).c_str(), (char *)0);
std::cout << "child exiting " << std::endl;
exit(1);
}
else if(pid > 0)
{
std::cout <<"child started with " << pid << std::endl;
}
else
{
std::cout << "fork failed" << std::endl;
}
}
while(true)
{
std::this_thread::sleep_for(std::chrono::seconds(100000));
}
return 0;
}
Child Code
#include <iostream>
#include <thread>
#include <chrono>
int main(int argc, char* argv[])
{
std::cout << " child started with id " << argv[1] << std::endl;
std::cout <<"child sleeping " << argv[1] << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1000));
std::cout << "child exiting " << argv[1] << std::endl;
return 0;
}
Output:
child started with 1834
child started with 1835
child exiting
child started with 1836
child exiting
child started with 1837
child started with 1838
child started with 1839
child exiting
child started with 1840
child started with 1841
child exiting
child started with 1842
child started with 1843
child exiting
child exiting
child exiting
child exiting
child exiting
child exiting
ps -ef shows all of my child processes as Defunct even though my parent is still alive.
Can you please explain what am I missing?
From the 'execlp' man page:
The exec() functions only return if an error has occurred. The return value is -1, and errno is set to indicate the error.
Since "child exiting" is being printed in two places, it's not obvious if it's exiting. You need to check it's return value and errno.
You need to reap the child-process as they exit. This is done using wait or waitpid calls.
Until the parent has done this, they will be visible as defunc / zombie processes. (init, process 1, is responsible for reaping all process that do not have a parent after they exit)

Why does the child of this class does not print?

I have made a class that is supposed to handle a subprocess but when I put a test print inside nothing happens, can someone tell me why ?
I have tried different types of print and combinations of fflush but it didn't solve the problem.
Here are my files:
Kitchen.cpp
Kitchen::Kitchen()
{
int wstatus;
this->_pid = fork();
if (this->_pid == 0) {
std::cout << "child: " << this->_pid << std::endl;
} else if (this->_pid == -1) {
throw("No child");
} else {
std::cout << "parent: " << this->_pid << std::endl;
waitpid(this->_pid, &wstatus, 1);
}
}
Kitchen::~Kitchen()
{
if (this->_pid > 0)
kill(this->_pid, SIGKILL);
}
Kitchen.hpp
#pragma once
#include <signal.h>
#include <unistd.h>
class Kitchen {
public:
Kitchen();
~Kitchen();
private:
pid_t _pid;
};
Reception.cpp
int Reception::run_shell(void)
{
this->_kitchens.push_back(Kitchen());
return (0);
}
Reception.hpp
#pragma once
#include <iostream>
#include <sstream>
#include "Kitchen.hpp"
class Reception
{
public:
Reception();
~Reception();
void repart(std::vector<Package> packed_order);
bool is_order(std::string input);
std::vector<Package> pack(std::string input);
int run_shell(void);
private:
std::vector<Kitchen> _kitchens;
};
main.cpp
int main(void)
{
Reception reception;
return (reception.run_shell());
}
Right now only the parent prints where as I would like both process to print.
Note that this code works outside of the class.
is it better now ?
Yes, better.
I copied your code to my Lubuntu 18.04, and using g++ 7.3.0-27, got the thing to compile.
The copied code on my system reproduced your error.
Hmmm.
So, I went looking for, and quickly found, my most recent experiment with fork. I do not understand why it works, and yours does not, they look similar enough to me.
I use a switch instead of your nested if-then-else's ... perhaps there exists a glitch in the nested if-then-else's? a faulty char transfer? But I doubt it.
So ... for pragmatic reasons, I (minimally?) changed your code to match my example.
Perhaps you can ask a better question as to why this seems to work, and in your version does not.
Hope this helps:
#include "../../bag/src/dtb_chrono.hh"
using namespace std::chrono_literals; // support suffixes like 100ms, 2s, 30us
#include <iostream>
using std::cout, std::cerr, std::flush, std::endl;
#include <string>
using std::string;
#include <thread>
using std::this_thread::sleep_for;
#include <vector>
using std::vector;
#include <cstring>
using std::strerror;
#include <unistd.h> // fork
#include <sys/wait.h> // waitpid
#include <cassert>
class Kitchen
{
pid_t child_pid;
time_t pt0; // child start time 0
time_t ct0; // parent start time 0
public:
Kitchen()
{
pt0 = time(0) + 2;
ct0 = time(0) + 1;
// 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.
child_pid = fork();
switch (child_pid)
{
case -1: { errnoExit (errno, "\n fork fail: ", -12); } break;
case 0: // child
{
std::cout << "\n i am child: " << child_pid << endl;
ChildProcess();
}
break;
default: // parent
{
std::cout << "\n i am parent, child_pid: " << child_pid << flush;
ParentProcess();
}
} // switch(child_pid)
} // Kitchen
~Kitchen()
{
if (child_pid > 0)
{ }; // { kill(child_pid, SIGKILL)};
}
void ChildProcess(void)
{
int i = 0;
do {
i += 1;
cout << "\n child " << i;
std::this_thread::sleep_for(100ms);
if (time(0) > ct0) break;
}while (true);
cout << "\n*** Child complete ***" << '\n';
}
void ParentProcess(void)
{
int i = 0;
do {
i += 1;
cout << "\n parent " << i ;
std::this_thread::sleep_for(100ms);
if (time(0) > pt0) break;
}while (true);
int wstatus;
waitpid(child_pid, &wstatus, 1); // see output -
// waitpid not effective because parent runs longer than child
// but causes no harm ...
//
// TBD - when parent run is shorter than child?
// appears that parent end halts child?
cout << "\n*** Parent complete ***" << '\n';
}
private:
void errnoExit(int err_no, const string message, int id) {
assert(0 != err_no); cerr << message << strerror(err_no);
assert(id < 0); exit(id); }
}; // class Kitchen
class Reception
{
public:
Reception() = default;
~Reception() = default;
int operator()(int argc, char* argv[]) { return run_shell(argc, argv); }
//void repart(std::vector<Package> packed_order);
//bool is_order(std::string input);
//std::vector<Package> pack(std::string input);
int run_shell(int /*argc*/, char** /*argv[]*/)
{
_kitchens.push_back(Kitchen());
return (0);
}
private:
vector<Kitchen> _kitchens;
}; // class Reception
int main(int argc, char* argv[]) { return Reception()(argc, argv); }
Typical Output:
i am parent, child_pid: 6727
i am child: 0
parent 1
child 1
parent 2
child 2
parent 3
child 3
parent 4
child 4
parent 5
child 5
parent 6
child 6
parent 7
child 7
parent 8
child 8
parent 9
child 9
parent 10
child 10
parent 11
child 11
parent 12
child 12
parent 13
child 13
parent 14
child 14
parent 15
child 15
parent 16
child 16
parent 17
child 17
parent 18
child 18
*** Child complete ***
parent 19
parent 20
parent 21
parent 22
parent 23
parent 24
parent 25
parent 26
parent 27
parent 28
*** Parent complete ***
The last else lacks curly braces, waitpid(this->_pid, wstatus, 1); is executed by both child and parent...
The parent process needs to be told to wait for any child processes to complete. I noticed your final else condition is missing the parentheses so only the one line after the else will be executed.
The other issue is the pointer wstatus. Because it's a pointer that isn't initialized, I'm not sure which behavior will be expressed. Change it to an int and in the waitpid call, use &wstatus.

Scheduler processes with signals SIGTSTP and SIGCONT on linux

Write a scheduler Round-Robin with the following characteristics:
The scheduler must accept quantum qt time and the processes to be performed as parameters on the command line with the following format:
./scheduler qt path_process1 startTime1 executionTime1 path_process2 startTime2 executionTime2 ...
Each of the processes that create and will rotate the scheduler should be a separate program that prints a message every 0.5s in the following format:
Program i: Messages printed: 1.
Program i: Messages printed: 2.
Program i: Messages ...
...
When cyclic initiation and termination of each process itself will print messages:
Process pid is executing.
//Execution of process pid
Process pid is suspended.
Stopping and execution processes will be with signals SIGTSTP and SIGCONT .
Consider and comment system behavior for small and large values ​​of the quantum time (e.g. qt = 0.5s, 1s, 2s, 4s) for five processes with the following starting and running times.
startTimes = [0,2,4,6,8]
execTimes = [3,6,4,5,2]
Given Hint:
To carry out a process child as a separate program, use the command execl (...).
For measuring the time elapsed from the start of operation of the scheduler, use the command gettimeofday (...).
Code
Scheduler.cpp
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <cstdio>
#include <sys/types.h>
#include <sys/time.h>
#include <signal.h>
#include <sys/signal.h>
using namespace std;
float qt;
int k,j,i;
int total_time=0;
int pass_time=0;
void stp_handler(int signal){
}
void con_handler(int signal){
}
int main(int argc, char *argv[])
{
int p=2;
int s=3;
int e=4;
int count=0;
signal(SIGTSTP,stp_handler);
signal(SIGCONT,con_handler);
int start_time[(argc-2)/3];
float execution_time[(argc-2)/3];
char *path_process[(argc-2)/3];
float remaining_time[(argc-2)/3];
timeval time;
int start,end;
if (argc < 2)
{
cout<<"You didn't enter any arguments" << endl;
exit(0);
}
else{
qt = atoi(argv[1]);
while (count < ((argc-2)/3) ){
path_process[count] = argv[p];
start_time[count] = atoi(argv[s]);
execution_time[count] = atoi(argv[e]);
remaining_time[count] = execution_time[count];
total_time = total_time + execution_time[count];
cout << path_process[count] << " " << start_time[count] << " " << execution_time[count] << endl;
p+=3;
s+=3;
e+=3;
count++;
}
}
i=0;
pid_t pid[count];
while(i<count){
pid_t par,child;
child=fork();
if (child==0){
par = getppid();
cout << "Child pid: " << i << " " << getpid() << endl << "Parent pid: " << par << endl;
char num[100]={0x0};
sprintf(num,"%d",i+1);
char pi[100]={0x0};
sprintf(pi,"%d",getpid());
execl(path_process[i],path_process[i],pi,num,(char*)0);
exit(0);
}
else{
sleep(1);
pid[i] = child;
i++;
}
}
i=0;
cout << endl << "Processes time: " << total_time << endl << endl;
gettimeofday(&time,NULL);
start = time.tv_sec;
while(pass_time<total_time){
for(j=0;j<count;j++){
if (pass_time<start_time[j]){
continue;
}
else if (remaining_time[j]<=0){
continue;
}
else if (remaining_time[j]>= qt){
kill(pid[j],SIGCONT);
usleep(qt*1000000);
kill(pid[j],SIGTSTP);
pass_time = pass_time + qt;
remaining_time[j]=remaining_time[j]-qt;
i++;
}
else{
kill(pid[j],SIGCONT);
usleep(remaining_time[j]*1000000);
kill(pid[j],SIGTSTP);
pass_time = pass_time + remaining_time[j];
remaining_time[j]=0;
i++;
}
}
}
sleep(1);
gettimeofday(&time,NULL);
end = time.tv_sec;
cout << "Scheduler time: " << end - start << endl;
for(i=0;i<count;i++)
kill(pid[i],SIGKILL);
return 0;
}
Signals.cpp
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <iostream>
#include <time.h>
#include <sys/wait.h>
#include <sys/signal.h>
using namespace std;
int j=1;
char* pid;
void sig_handler(int signal){
if (signal == SIGCONT){
cout << endl << "Process " << pid << " is executing." << endl << endl;
j=0;
}
else if (signal == SIGTSTP){
cout << endl << "Process " << pid << " is suspended." << endl << endl;
j=1;
}
}
main(int argc, char *argv[])
{
signal(SIGTSTP,sig_handler);
signal(SIGCONT,sig_handler);
pid = argv[1];
int i=1;
while(1){
while(j==0){
cout << "Program: " << argv[2] << " messages printed: " << i << endl;
usleep(500000);
i++;
}
}
}
Output from Scheduler
(This is correct I guess)
process1 0 3
process2 2 6
process2 4 4
process3 6 5
process4 8 2
Child pid: 0 3406
Parent pid: 3405
Child pid: 1 3407
Parent pid: 3405
Child pid: 2 3408
Parent pid: 3405
Child pid: 3 3409
Parent pid: 3405
Child pid: 4 3410
Parent pid: 3405
Processes time: 20
Output from Signals
I get nothing but as I mentioned above I expect it to be somehow like this.
Program i: Messages printed: 1.
Program i: Messages printed: 2.
Program i: Messages ...
...
When cyclic initiation and termination of each process itself will print messages:
Process pid is executing.
//Execution of process pid
Process pid is suspended.
P.S: In order to get the scheduler to work I compile it and run it with
>./scheduler 0.5 process1 0 3 process2 2 6 process2 4 4 process3 6 5 process4 8 2
Why don't the signals cause any output?

Running 3 child processes

I have three child process and one parent.
I want the program runs in that order [ Child1 then child2 then child3 then parent ].
I have been trying to do with the follwing code but it dose not give me right sequence!
Code:
#include<iostream>
#include<string.h>
#include<fstream>
#include<cstdlib>
#include <sys/types.h>
#include <sys/wait.h>
using namespace std;
int main()
{
pid_t ch11;
pid_t ch22;
pid_t ch33;
int ch1 = fork();
int ch2 = fork();
int ch3 = fork();
if (ch1==0) //child1
{ cout<<"this is child 1\nGoing from 1 to child 2 ...\n\n";
exit(0);
}
else if ( ch2==0)
{ waitpid(ch11,0,0);
cout<<"This is child 2\nGoing from 2 To Child 3 ...\n\n";
exit(0);
}
else if (ch3==0)
{ waitpid(ch22,0,0);
cout<<"This is child 3\nFineshed !! going from 3 to parent\n\n";
exit(0);
}
else
{ waitpid(ch33,0,0);
cout<<"This is parent , waited the whole childes to finish !!\n\n";
exit(0);
}
return 0 ;
}
Output:
ubuntu#ubuntu-desktop:~$ c++ a.cpp -o p1
ubuntu#ubuntu-desktop:~$ ./p1
This is child 2
Going from 2 To Child 3 ...
this is child 1
Going from 1 to child 2 ...
this is child 1
Going from 1 to child 2 ...
this is child 1
Going from 1 to child 2 ...
This is child 2
Going from 2 To Child 3 ...
This is child 3
Fineshed !! going from 3 to parent
this is child 1
Going from 1 to child 2 ...
This is parent , waited the whole childs to finish.
I know that it will be solved by using waitpid() function , I think im using the waitpid() wrong.
Here's a better instrumented version of your code; it includes the PID in the output, and the outputs are one line each.
#include <iostream>
#include <cstdlib>
#include <sys/wait.h>
#include <unistd.h>
using namespace std;
int main()
{
int ch1 = fork();
int ch2 = fork();
int ch3 = fork();
if (ch1 == 0) // child1
{
cout << (int)getpid() << ": This is child 1 - Finished\n";
exit(0);
}
else if (ch2 == 0)
{
waitpid(ch1, 0, 0);
cout << (int)getpid() << ": This is child 2 - Finished\n";
exit(0);
}
else if (ch3 == 0)
{
waitpid(ch2, 0, 0);
cout << (int)getpid() << ": This is child 3 - Finished!\n";
exit(0);
}
else
{
waitpid(ch3, 0, 0);
cout << (int)getpid() << ": This is parent - waited for all children to finish!\n";
exit(0);
}
return 0;
}
Sample output:
$ ./3kids
40287: This is child 3 - Finished!
40285: This is child 1 - Finished
40286: This is child 2 - Finished
40290: This is child 1 - Finished
40289: This is child 2 - Finished
40288: This is child 1 - Finished
40284: This is parent - waited for all children to finish!
40291: This is child 1 - Finished
$
As you can see, there is one process that considers itself to be child 3, two processes that consider themselves to be child 2, and four processes that consider themselves to be child 1 and one that considers itself to be the parent. This is consistent with the unconstrained forking which creates 8 processes.
To have 3 children only, and to wait for each in turn, you need code more like:
#include <iostream>
#include <cstdlib>
#include <sys/wait.h>
#include <unistd.h>
using namespace std;
void child(int n)
{
flush(cout); // No pending output
int pid = fork();
if (pid < 0)
cerr << (int)getpid() << ": failed to fork\n";
else if (pid == 0)
{
cout << (int)getpid() << ": This is child " << n << " - Finished\n";
exit(0);
}
else
{
int corpse;
int status;
while ((corpse = wait(&status)) != -1)
cout << (int)getpid() << ": PID " << corpse << " exited with status "
<< status << "\n";
}
}
int main()
{
child(1);
child(2);
child(3);
cout << (int)getpid() << ": This is parent - waited for all children to finish!\n";
return 0;
}
Sample output:
$ ./3kids
40336: This is child 1 - Finished
40335: PID 40336 exited with status 0
40337: This is child 2 - Finished
40335: PID 40337 exited with status 0
40338: This is child 3 - Finished
40335: PID 40338 exited with status 0
40335: This is parent - waited for all children to finish!
$
Despite your comment "the code is working but it gives me the wrong sequence of executing" the whole thing is still completely incorrect and it is obvious you did not understand what other people tried to say, hence I'll make an attempt here.
int main()
{
pid_t ch11;
pid_t ch22;
pid_t ch33;
What is the purpose of these variables?
int ch1 = fork();
Have you read fork manpage? It clearly states when a child process is created it returns 0 in the child and pid in the parent. It can also fail, so you should have checked for that.
With this in mind....
int ch2 = fork();
Both the child and the parent reach this line. Hence previously created child forks as well.
int ch3 = fork();
Guess what.
if (ch1==0) //child1
{ cout<<"this is child 1\nGoing from 1 to child 2 ...\n\n";
Except you are not (see below).
exit(0);
Should be _Exit.
}
else if ( ch2==0)
{ waitpid(ch11,0,0);
What? ch11 is not even initialized, so what was this supposed to accomplish?
Do you compile your code with warnings enabled?
In general I don't know if you were trying to make the children fork and thus create a chain of for processes with parent<->child relationship or you wanted 3 children of the same parent process. If the latter this is just bad, if the former this is even more wrong since you would not be able to just wait for such a process.
[snip the rest]
Finally, let's address
the wrong sequence of executing
What?
There are no guarantees whatsoever as to the order of execution of your processes. In fact any number of them can execute for any amount of time and be scheduled out multiple times before any other number of them even gets a chance to run.
Given what was shown up to this point I'm inclined to guess you either misunderstood your homework assignment or are approaching it quite "unconventionally". Either way, I strongly recommend you state the actual problem which was supposed to be addressed with your code.