简体   繁体   English

这是在linux编程中同时处理文件的有效方法吗?

[英]Is this an efficient way to concurrently process files in linux programming?

I want to process different files simultaneously. 我想同时处理不同的文件。 My program will get the first argument which is a file which contains names( absolute paths ) of different files on my pc and the second argument the name of the program to run(say anotherProgram for now). 我的程序将得到第一个参数,它是一个文件,其中包含我的电脑上不同文件的名称( absolute paths ),第二个参数是要运行的程序的名称(现在说是anotherProgram )。 So one such file could be something like this 所以一个这样的文件可能是这样的

/usr/home/username/Desktop/folder/file.txt
/usr/home/username/Desktop/file2.txt
/usr/home/username/Desktop/folder/directory/anotherfile.txt
/usr/home/username/Desktop/folder/file3.txt
/usr/home/username/Documents/folder/file5.txt
/usr/home/username/Desktop/file10.txt
/usr/home/username/Desktop/folder/file9.txt

Now my C program will read each line and then open that particular file using low-level open system call. 现在我的C程序将读取每一行,然后使用低级开放系统调用打开该特定文件。 Now I will fork of a process and in the child I will perform the task( anotherProgram in our example) on that particular file descriptor whereas the parent goes back and opens the second file(on second line) and forks again and so on and so forth. 现在我将在一个进程的fork中,在子进程中,我将在该特定文件描述符上执行任务(在我们的示例中为anotherProgram ),而父进程返回并打开第二个文件(在第二行)并再次分叉,依此类推向前。 (see question 2) (见问题2)

This anotherProgram will be exec'd with the file descriptor as the parameter. 这个anotherProgram将以文件描述符作为参数执行。 This way in my exec'd child, I can still use the same file descriptor to refer to the same file even after forking right? 这样在我的exec'd孩子中,即使分叉后,我仍然可以使用相同的文件描述符来引用同一个文件吗? and hence process concurrently? 因此并行处理? This anotherProgram could be something that just reads from a file descriptor etc. 这个anotherProgram可能只是从文件描述符等读取。

So now that I have said all this, I have a few questions. 所以现在我说了这一切,我有几个问题。

  1. Is this an efficient way to process files concurrently? 这是同时处理文件的有效方法吗? I don't want threads, but I want to use fork someway to do this. 我不想要线程,但我想使用fork来做到这一点。

  2. Also since I run fork in a loop in parent, every new child inherits previous file descriptors, like for example, the first child would inherit '3' and the second child would inherit '3' and '4' and the third child would inherit '3', '4' and '5' file descriptors. 此外,由于我在父级循环中运行fork,每个新子级都继承以前的文件描述符,例如,第一个子级将继承“3”,第二个子级将继承“3”和“4”,第三个子级将继承'3','4'和'5'文件描述符。 So is there a way to avoid this so that child 'i' inherits only 'ith' file descriptor? 那么有没有办法避免这种情况,以便孩子'我'只继承'ith'文件描述符?

TLDR; TLDR; I have a list of files and a program which I want to apply to all of them concurrently using fork, dup, exec or piping, without any threads. 我有一个文件列表和一个程序,我想使用fork,dup,exec或piping同时应用于所有这些文件和程序,没有任何线程。 How do I do this? 我该怎么做呢?

I have a list of files and a program which I want to apply to all of them concurrently using fork, dup, exec or piping, without any threads. 我有一个文件列表和一个程序,我想使用fork,dup,exec或piping同时应用于所有这些文件和程序,没有任何线程。 How do I do this? 我该怎么做呢?

Your outlined design will work, but can be improved if the parent doesn't need to do anything else with a file descriptor after passing it to the child. 您概述的设计将起作用,但如果父项在将文件描述符传递给子项后不需要对文件描述符执行任何其他操作,则可以进行改进。 In this case, the parent can close the file, so that the next opened file can use the same descriptor and there's no danger to use up the descriptors. 在这种情况下,父级可以关闭文件,以便下一个打开的文件可以使用相同的描述符,并且没有使用描述符的危险。 Moreover, a well-known descriptor can be used, so that there's no need to pass it to the child task. 此外,可以使用众所周知的描述符,因此不需要将其传递给子任务。 E. g.: E. g。:

#include <stdio.h>
#include <string.h>
#include <limits.h>

main(int argc, char *argv[])
{
    if (argc != 3)
        return printf("usage: %s 'namesFile' 'anotherProgram'\n", *argv), 1;
    FILE *names = fopen(argv[1], "r");
    if (!names) return perror(argv[1]), 1;
    char path[PATH_MAX];
    while (fgets(path, sizeof path, names))
    {
        char *np = strchr(path, '\n');
        if (np) *np = '\0';
        FILE *input = freopen(path, "r", stdin);    // reuse well-known 'stdin'
        if (!input) { perror(path); continue; }
        if (fork()) return execvp(argv[2], argv+2), perror(argv[2]), 1;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM