0

First of all I'm new to Linux and processes, so I couldn't understand the logic of fork() exactly. I want to create a process tree from user input and display this tree with using 'pstree'. However my code displays the tree more than one times. I think the reason is fork() copies the 'pstree' command, I couldn't solve this problem. The code is like that:

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string>
#include<sys/types.h>
#include<sys/wait.h>

using namespace std;

int main(int argc, char* argv[])
{

    int forkSize, currentPid,b=0;
    forkSize=atoi(argv[1]);


    int parentPid=getpid();
    
    for(int i=0;i<forkSize;i++)
    {
        
        currentPid = fork();
        
        if (currentPid<0)
        {
            cout<<"Error in fork"<<endl;
            exit(0);
        }
        if(currentPid == 0)
        {   
            cout << "Child process: My parent id = " << getppid() << endl;
            cout << "Child process: My process id = " << getpid() << endl;
        }
        else
        {   
            cout << "Parent process. My process id = " << getpid() << endl;
            cout << "Parent process. Value returned by fork() = " << currentPid << endl;
        }
       
    }
    
    fflush(stdout);
    
    char mychar[500];
    sprintf(mychar, "pstree -p -U %d", parentPid);
    system(mychar);
    fflush(stdout);
    
    cout<<endl;
    
    return 0;
}

When I try this code with input 4, the output looks like that:

output

I can't understand why it displays everything again and again. Is there a way to display the tree for once? I would be really glad if help me about that.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • 1
    Your forks create multiple processes, and each will go on to run the command. If you don't want them to do that, you should have the child processes exit before they start calling the command. – that other guy Apr 06 '21 at 22:52
  • 1
    You should also make the child processes sleep for a couple of seconds, so they'll still be there when the parent runs `pstree`. – Barmar Apr 06 '21 at 22:56
  • 1
    @thatotherguy I think he wants to have the children fork more children, so he can see a big tree of all the processes. So they can't exit immediately. – Barmar Apr 06 '21 at 22:58
  • @thatotherguy - How can I exit before the calling the command? I tried to exit in the 'if(currentPid==0)' section but it doesn't display the tree what I want. Maybe I understood you wrong. As I said I'm new to this field and my mind get confused so much. I'm sorry about that. – quixoticmind Apr 06 '21 at 23:20

1 Answers1

0

All the processes eventually get to the code that runs pstree. You should check there that you're in the original parent process, and only run pstree in that case.

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string>
#include<sys/types.h>
#include<sys/wait.h>

using namespace std;

int main(int argc, char* argv[])
{

    int forkSize, currentPid,b=0;
    forkSize=atoi(argv[1]);

    int parentPid=getpid();
    
    for(int i=0;i<forkSize;i++)
    {
        
        currentPid = fork();
        
        if (currentPid<0)
        {
            cout<<"Error in fork"<<endl;
            exit(0);
        }
        if(currentPid == 0)
        {   
            cout << "Child process: My parent id = " << getppid() << endl;
            cout << "Child process: My process id = " << getpid() << endl;
            sleep(1);
        }
        else
        {   
            cout << "Parent process. My process id = " << getpid() << endl;
            cout << "Parent process. Value returned by fork() = " << currentPid << endl;
        }
       
    }
    
    if (getpid() == parentPid) {
        char mychar[500];
        sprintf(mychar, "pstree -p -U %d", parentPid);
        system(mychar);
    }
        
    return 0;
}

BTW, endl flushes output, you don't need to call fflush(stdout);. Also, that's C, but your code is C++.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • To be honest I didn't know the purpose of 'fflush(stdout)', I just saw it from somewhere and I thought that maybe It will help me, so I used it. Haha. But I understood it, thanks for the information. Also your solution was looking logical to me but when I try it with the input 4, it displays 4 children of a parent. But why don't children have their own children too? I was supposing that every children would have 2 new children in each step, so there would be a binary tree. Maybe I'm thinking wrong... But thanks for the solution. – quixoticmind Apr 06 '21 at 23:30