这是在 linux 编程中并发处理文件的有效方法吗?
Is this an efficient way to concurrently process files in linux programming?
我想同时处理不同的文件。我的程序将获得第一个参数,它是一个文件,其中包含我电脑上不同文件的名称(absolute paths
),第二个参数是程序的名称 运行(比如 anotherProgram
现在)。所以一个这样的文件可能是这样的
/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
现在我的 C 程序将读取每一行,然后使用 low-level 打开系统调用打开该特定文件。现在我将分叉一个进程,在 child 中我将在该特定文件描述符上执行任务(在我们的示例中为 anotherProgram
),而 parent 返回并打开第二个文件(在第二行)并再次分叉等等。 (见问题 2)
这个另一个程序将以文件描述符作为参数执行。这样在我的 exec'd child 中,我仍然可以使用相同的文件描述符来引用相同的文件,即使在分叉之后也是如此吗?因此并发处理?这个 anotherProgram
可能只是从文件描述符等中读取的内容。
既然我已经说了这么多,我有几个问题。
这是并发处理文件的有效方法吗?我不想要线程,但我想以某种方式使用 fork 来执行此操作。
此外,由于我 运行 在 parent 中循环 fork,每个新的 child 都继承了以前的文件描述符,例如,第一个 child 将继承 '3',第二个 child 将继承 '3' 和 '4',第三个 child 将继承 '3'、'4' 和 '5' 文件描述符。那么有没有办法避免这种情况,使 child 'i' 仅继承 'ith' 文件描述符?
TLDR;我有一个文件列表和一个程序,我想使用 fork、dup、exec 或管道同时应用到所有这些文件和程序,没有任何线程。我该怎么做呢?
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. How do I do this?
您的概述设计会起作用,但如果父项在将文件描述符传递给子项后不需要对文件描述符执行任何其他操作,则可以进行改进。在这种情况下,父级可以关闭该文件,以便下一个打开的文件可以使用相同的描述符,并且没有用完描述符的危险。此外,可以使用 well-known 描述符,因此无需将其传递给子任务。例如:
#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 = '[=10=]';
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;
}
}
我想同时处理不同的文件。我的程序将获得第一个参数,它是一个文件,其中包含我电脑上不同文件的名称(absolute paths
),第二个参数是程序的名称 运行(比如 anotherProgram
现在)。所以一个这样的文件可能是这样的
/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
现在我的 C 程序将读取每一行,然后使用 low-level 打开系统调用打开该特定文件。现在我将分叉一个进程,在 child 中我将在该特定文件描述符上执行任务(在我们的示例中为 anotherProgram
),而 parent 返回并打开第二个文件(在第二行)并再次分叉等等。 (见问题 2)
这个另一个程序将以文件描述符作为参数执行。这样在我的 exec'd child 中,我仍然可以使用相同的文件描述符来引用相同的文件,即使在分叉之后也是如此吗?因此并发处理?这个 anotherProgram
可能只是从文件描述符等中读取的内容。
既然我已经说了这么多,我有几个问题。
这是并发处理文件的有效方法吗?我不想要线程,但我想以某种方式使用 fork 来执行此操作。
此外,由于我 运行 在 parent 中循环 fork,每个新的 child 都继承了以前的文件描述符,例如,第一个 child 将继承 '3',第二个 child 将继承 '3' 和 '4',第三个 child 将继承 '3'、'4' 和 '5' 文件描述符。那么有没有办法避免这种情况,使 child 'i' 仅继承 'ith' 文件描述符?
TLDR;我有一个文件列表和一个程序,我想使用 fork、dup、exec 或管道同时应用到所有这些文件和程序,没有任何线程。我该怎么做呢?
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. How do I do this?
您的概述设计会起作用,但如果父项在将文件描述符传递给子项后不需要对文件描述符执行任何其他操作,则可以进行改进。在这种情况下,父级可以关闭该文件,以便下一个打开的文件可以使用相同的描述符,并且没有用完描述符的危险。此外,可以使用 well-known 描述符,因此无需将其传递给子任务。例如:
#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 = '[=10=]';
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;
}
}