C++ fork() - 如何使用 fork 和 pstree 显示进程树?

Posted

技术标签:

【中文标题】C++ fork() - 如何使用 fork 和 pstree 显示进程树?【英文标题】:C++ fork() - How to display process tree using fork and pstree? 【发布时间】:2021-04-06 22:37:58 【问题描述】:

首先,我是 Linux 和进程的新手,所以我无法准确理解 fork() 的逻辑。我想从用户输入创建一个进程树并使用“pstree”显示这个树。但是,我的代码不止一次显示树。我认为原因是 fork() 复制了“pstree”命令,我无法解决这个问题。代码是这样的:

#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;

当我使用输入 4 尝试此代码时,输​​出如下所示:

output

我不明白为什么它会一次又一次地显示所有内容。有没有办法一次显示树?如果能帮助我,我会很高兴的。

【问题讨论】:

你的分叉创建了多个进程,每个进程都将继续运行命令。如果您不希望他们这样做,您应该让子进程在它们开始调用命令之前退出。 你还应该让子进程休眠几秒钟,这样当父进程运行pstree时它们仍然会在那里。 @thatotherguy 我想他想让孩子分叉更多的孩子,这样他就可以看到所有进程的大树。所以他们不能立即退出。 @thatotherguy - 如何在调用命令之前退出?我试图退出 'if(currentPid==0)' 部分,但它没有显示我想要的树。也许我理解错了。正如我所说,我是这个领域的新手,我的头脑非常混乱。对此我很抱歉。 【参考方案1】:

所有进程最终都会到达运行pstree 的代码。您应该在那里检查您是否处于原始父进程中,并且在这种情况下只运行pstree

#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;

顺便说一句,endl 刷新输出,你不需要调用fflush(stdout);。另外,那是 C,但你的代码是 C++。

【讨论】:

说实话我不知道'fflush(stdout)'的用途,我只是从某个地方看到它,我认为它可能对我有帮助,所以我使用了它。哈哈。不过我明白了,谢谢你的信息。您的解决方案对我来说也很合乎逻辑,但是当我使用输入 4 尝试它时,它会显示父母的 4 个孩子。但是为什么孩子没有自己的孩子呢?我假设每个孩子每一步都会有 2 个新孩子,所以会有一棵二叉树。也许我想错了...但是感谢您的解决方案。

以上是关于C++ fork() - 如何使用 fork 和 pstree 显示进程树?的主要内容,如果未能解决你的问题,请参考以下文章

虚幻4与现代C++:使用TaskGraph实现Fork-Join模型

虚幻4与现代C++:使用TaskGraph实现Fork-Join模型

为啥在调用 c++ fork 函数之前创建的值没有被父进程和子进程修改两次?

C++ Fork Join 并行阻塞

C++ fork 进程但不是子进程

调用 fork() 后 SSL_accept 挂起