c++ 为什么只有第一个子进程打印出内容?

wfypjpf4  于 2022-11-19  发布在  其他
关注(0)|答案(1)|浏览(87)

我正在工作的程序叫做myfile -它应该在某个搜索路径中找到一个文件。你也应该能够搜索多个文件,如果是这样的话,我必须fork创建多个子进程().问题是,我没有打印出预期的结果。如果我搜索多个文件,只有第一个文件被“返回”。我认为这与else语句中的第二个for有关。为了调试,我打印出了每个子进程的PID。问题是不是可能是子进程在同一时间使用相同的变量?

代码:'

#include<iostream>
#include<dirent.h>
#include<string.h>
#include<unistd.h>
#include<sys/wait.h>
#include<stdlib.h>
using namespace std;
int main(int argc, char** argv)
{
    struct dirent *d;
    DIR *dr;
    dr = opendir(argv[1]);

    pid_t pid;
    int numberOfFiles = argc - 2;
    if(dr!=NULL){
        if(numberOfFiles == 1){
            // normal search without fork
            for(d=readdir(dr); d!=NULL; d=readdir(dr)){
                if(strcmp(d->d_name, argv[argc-1]) == 0){
                    cout << "<" << getpid() << ">: " << argv[argc-1] << ": <" << realpath(argv[argc-1], NULL) << ">" <<endl;
                }
            }
        }else{
            // search with fork
            for(int i = 2; i < argc; i++){
                if(fork() == 0){
                    cout << "Current PID: " << getpid() << " " << argv[i] <<endl;
                    for(d=readdir(dr); d!=NULL; d=readdir(dr)){
                        if(strcmp(d->d_name, argv[i]) == 0){
                            cout << "Current i=" << i << " "<< "<" << getpid() << ">: " << argv[i] << ": <" << realpath(argv[i], NULL) << ">" <<endl;
                        }
                    }
                    exit(0);
                }
            }
            for(int i=0; i < numberOfFiles; i++){
                wait(NULL);
            }
        }
    }else
        cout<<"\nError Occurred!"<<endl;
    cout<<endl;
    return 0;
}

`**终端输出截图:**x1c 0d1x
问题是,我没有打印出预期的结果。如果我搜索多个文件,只有第一个文件被“返回”。我认为这与else语句中的第二个for有关。为了调试,我打印出了子进程的每个PID。问题是不是可能是子进程在同一时间使用相同的变量?

9rnv2umw

9rnv2umw1#

看起来像是opendirreaddir和重复使用变数的问题。我将您的程式精简为:

int main(int argc, char **argv)
{
    struct dirent *d;
    DIR *dr;
    dr = opendir(argv[1]);

    for (int i = 2; i < argc; i++)
    {
        if (fork() == 0)
        {
            cout << "Current PID: " << getpid() << " " << argv[i] << endl;
            for (d = readdir(dr); d != NULL; d = readdir(dr))
            {
                cout << getpid() << "\t" << d->d_name << endl;
            }
            exit(0);
        }
    }

    for (int i = 0; i < argc - 2; i++)
        wait(NULL);
}

并得到以下输出(来自./testfork ../bla 1 2):

Current PID: 17197 1
Current PID: 17198 2
17198   test.txt
17198   ..
17198   .

这表明,一旦一个进程读取到以readdir结尾的内容,那么另一个进程什么也得不到。

int main(int argc, char **argv)
{
    struct dirent *d;
    DIR *dr;

    for (int i = 2; i < argc; i++)
    {
        if (fork() == 0)
        {
            dr = opendir(argv[1]);  // <- Here
            cout << "Current PID: " << getpid() << " " << argv[i] << endl;
            for (d = readdir(dr); d != NULL; d = readdir(dr))
            {
                cout << getpid() << "\t" << d->d_name << endl;
            }
            exit(0);
        }
    }

    for (int i = 0; i < argc - 2; i++)
        wait(NULL);
}

输出变为:

Current PID: 17751 1
17751   test.txt
17751   ..
17751   .
Current PID: 17752 2
17752   test.txt
17752   ..
17752   .

我不太明白为什么会发生这种情况,因为fork的工作方式应该确保每个进程都获得自己的内存副本(尽管可能只有在写入之后)。因此,当一个进程修改dr时,该更改不应该反映在其他进程中。
也许这是由于dr实际上是通过系统调用(通过readdir)而不是通过进程直接更改的?

相关问题