【问题标题】:Too many open files when opening and closing large numbers of files打开和关闭大量文件时打开的文件过多
【发布时间】:2015-09-03 21:12:23
【问题描述】:

我正在运行一些代码,这些代码会打开多个文件以读取数据,对其进行处理,然后通过实验工具关闭文件。每次完成大量处理时,工具都会更改一些参数,然后使用更新的参数再次运行相同的代码。

当我运行少量实验时没有问题,当程序退出时,所有内存都被释放。但是,如果我尝试运行大量实验,代码总是在调用处理代码大约 1000 次后崩溃。我检查了在系统的每个单独部分中使用fopen 打开的每个文件都使用fclose 关闭,但问题仍然存在,Valgrind 输出

==11892== Warning: invalid file descriptor 1030 in syscall open()
==11892== Warning: invalid file descriptor 1030 in syscall dup()
Could not access specified file: Too many open files

大约 1000 次迭代后,perror 给出“打开的文件太多”错误。为了打开更多文件,我必须做些什么来重置文件描述符计数?

edit:查看运行时的lsof -p 输出,似乎正在打开的文件类型是DIR。我正在访问的文件位于不同的目录中。我目前正在使用fopen("path/to/directory/file.txt", "w") 打开文件。我需要做些什么来释放我使用的文件描述符吗?

这是lsof 输出的摘录:

lt-launch 12101 michal   25r   DIR    8,1     4096 3537225 /directory/reference/20
lt-launch 12101 michal   26r   DIR    8,1     4096 3537238 /directory/reference/21
lt-launch 12101 michal   27r   DIR    8,1     4096 3537251 /directory/reference/22

edit2:有问题的代码如下:

FILE *fp;

printf("Retrieving event data from file %s\n", filename);

if ((fp = fopen(filename, "r")) == NULL){
perror("Could not access specified file");
exit(1);
}

char* line = malloc(MAX_LINE_LENGTH);
char* lref = line;
double_arr* event_times = init_double_arr(DEFAULT_ARR_SIZE);

// Get data from file...

if (i == 0){// we found no events in the given interval
free_double_arr(event_times);
free(lref);
fclose(fp);
return NULL;
}
event_times->data = realloc(event_times->data, i * sizeof(double));
event_times->len = i;
fclose(fp);
free(lref);

return event_times;

edit3:虽然此时是程序崩溃的地方,但原因实际上是在代码的其他地方打开了错误的目录。请参阅下面的答案以了解问题所在。

【问题讨论】:

  • 您确定需要打开这么多文件吗?
  • 它们永远不会同时打开——每次迭代最多打开三个文件,完成后关闭它们。
  • 请把代码的关键部分贴出来……
  • 你在检查fclose()的返回值吗?它会警告你一个错误......最可能的原因是你传递了错误的描述符 - 例如使用相同的文件描述符不断关闭。
  • 如果没有复制问题的代码就很难说。但是,如果grep -r SomethingReallyObscure / 在您的系统上工作 [没有显示“打开的文件过多”的错误] [假设您的系统有超过 4000 个文件,我希望它有,因为您收到此错误],那么它很可能是代码中的问题,尤其是打开文件后如何关闭文件。

标签: c


【解决方案1】:

如果打开的文件太多,处理后不要关闭文件...

您发布的代码会关闭所有代码路径上的文件(直接exiting 时除外,但这没关系),所以.. 我看到两种可能的情况:

  • 您未发布的代码中有提前返回,不会关闭文件
  • 您使用其他代码破坏了内存,覆盖了 fp,因此您并没有真正关闭它 - 您可以通过检查 fclose 的返回值来验证这一点。

【讨论】:

    【解决方案2】:

    程序在尝试打开文件时崩溃,但问题的根源在其他地方。每个实验打开的文件都在新目录中,每个文件都是使用一些错误代码创建的,该代码称为opendir(),然后使用free() 释放分配给产生的DIR 指针的内存。将free() 调用更改为dirclose() 解决了这个问题。

    【讨论】:

      猜你喜欢
      • 2012-10-01
      • 1970-01-01
      • 2017-05-26
      • 2017-12-09
      • 1970-01-01
      • 2015-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多