quixoticmind
quixoticmind

Reputation: 1

C++ fork() - How to display process tree using fork and pstree?

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.

Upvotes: 0

Views: 1523

Answers (1)

Barmar
Barmar

Reputation: 780929

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++.

Upvotes: 0

Related Questions