【发布时间】:2019-05-21 09:50:42
【问题描述】:
我有一个 C++ 和一个 Python 代码通过在一个目录中读取和写入文件来相互通信,多次。他们还在读取数据后删除了一些文件。这是在 Ubuntu 17.10 上完成的。
但是,在多次执行此序列(>6000 - 7000 次)之后,我收到以下错误:
Couldn't open the directory: Too many open files
此错误消息始终从 C++ 代码传递。
对于C++代码:
数据写入使用:
std::string opfilepath("/some/path/");
ofstream opfile;
opfile.open (opfilepath);
opfile<<"some stuff"<<endl;
opfile.close()
目录中的文件数使用以下方法计算:
DIR* dirFile = opendir( path );
int count = 0;
if ( dirFile )
{
struct dirent* hFile;
errno = 0;
while (( hFile = readdir( dirFile )) != NULL )
{
if ( !strcmp( hFile->d_name, "." )) continue;
if ( !strcmp( hFile->d_name, ".." )) continue;
if ( strstr( hFile->d_name, ext.c_str() ))
count++;
}
}
closedir( dirFile );
读取文件使用:
std::ifstream file("/some/path");
if (file.is_open())
{
//do something
}
file.close();
文件被删除使用:
boost::filesystem::remove("/some/file.txt")
对于 Python 代码:
文件使用以下方式写入:
f = open("/some/file.txt", "a")
f.write("some stuff")
f.close()
使用以下方式读取文件:
fp = open(path)
lines = fp.read().splitlines()
fp.close()
文件被删除使用:
os.remove("/some/path/and/file.txt")
所有文件都以模块化方式打开和关闭,同步似乎不是问题。但我一直看到打开的文件太多,而且总是在固定数量的迭代之后。
任何想法为什么会发生这种情况?
【问题讨论】:
-
这是否在多个线程或进程中运行?围绕此代码是否有任何错误处理,或者是否有可能捕获到不关闭文件的异常?通常最好使用适当的错误处理(在 python 中使用
with语句)进行文件操作,并在 C 中使用 try catch 块来确保即使在文件打开和文件关闭之间引发异常的情况下也能关闭文件。 -
你可以检查你的“ulimit -n”参数,还提供进程抛出错误打开的文件描述符的总数,你可以这样做 - ls /proc/
/fd |厕所-l。这将使您了解文件描述符发生了什么。 -
哪个进程收到
Couldn't open the directory: Too many open files错误消息? C++ 那个? Python 那个? -
@metsburg 继续检查命令“lsof -p
”的输出,它将为您提供导致问题的未打开文件的确切名称。正如你所说,这是一个新的观察结果,没有。 fd 随时间增加,如果不是。每次迭代的 fd 都在增加 - 始终如一,那么可以看出您应该在迭代中的相关点使用带有断点的 gdb 以及 lsof 使用 - 来根本导致确切的问题。 -
@metsburg 或者您可以运行 valgrind --track-fds=yes /path/to/cppBin,请注意,这些只是缩小范围的技术。
标签: python c++ file-io resource-leak