C++ 管道,打开的文件太多,Errno 25
Posted
技术标签:
【中文标题】C++ 管道,打开的文件太多,Errno 25【英文标题】:C++ Pipe, Too Many Open Files, Errno 25 【发布时间】:2015-02-09 15:43:46 【问题描述】:我有一个在 OS X (10.10/Yosemite) 上运行的旧 C++ 应用程序。
当我调试应用程序时,以下代码行出现异常:
// create pipe
int pipefd[2];
int piperet = pipe(pipefd);
if( piperet )
wcsncpy(errbuf, CEmpError::GetErrorText(CEmpError::ERR_SYSTEM, L"Can't create pipe for IPC.", errno).c_str(), errbuflen);
CEmpError::LogError(errbuf);
return CEmpError::ERR_SYSTEM; //= 115
所以应用程序正在运行并执行这行代码几次。过了一会儿pipette
是-1
。 errno
错误代码是 25。
经过一番研究,这意味着“打开的文件太多”。是否有解决方法来关闭所有这些打开的文件?还是可以知道哪些文件打开的太多?
当我输入终端 ulimit -a
时,我得到:
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
file size (blocks, -f) unlimited
max locked memory (kbytes, -l) unlimited
max memory size (kbytes, -m) unlimited
open files (-n) 2560
pipe size (512 bytes, -p) 1
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 709
virtual memory (kbytes, -v) unlimited
所以我不是超级c++-pro,这里需要的代码行。猜猜所有不需要的管道或 pipefd 将被关闭。
// create pipe
int pipefd[2];
int piperet = pipe(pipefd);
if( piperet )
wcsncpy(errbuf, CEmpError::GetErrorText(CEmpError::ERR_SYSTEM, L"Can't create pipe for IPC.", errno).c_str(), errbuflen);
CEmpError::LogError(errbuf);
return CEmpError::ERR_SYSTEM;
CEmpError *pError = 0;
// after transfer the execution bit could be reset, so set the rights back
chmod(args[0], S_IWUSR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH );
pid_t pid = fork();
if(pid == 0)
// child process
close(pipefd[0]); // close reading end
int fd = pipefd[1];
// redirect stdout and stderr to pipe
dup2(fd, STDOUT_FILENO);
dup2(fd, STDERR_FILENO);
close(fd); // not needed anymore
// execute steup.sh with built argument list
execvp(args[0], (char**)args);
// if we ever reached this line the exec failed and we need to report error to parent process
// once we are in child process we will print the error into stdout of our child process
// and parent process will parse and return it to the caller.
char buf[128];
sprintf(buf, "setup.sh:ERROR:PI%03d",CEmpError::ERR_EXEC);
perror(buf);
// keep the process alive until the parent process got the error from the pipe and killed this child process
sleep(5);
return CEmpError::ERR_EXEC;
else if (pid > 0)
// parent process
delete[] args[0]; // release memory allocated to f.
delete[] args[3]; // release memory allocated to log f.
delete[] args[5]; // release memory allocated to pn
close(pipefd[1]);
pParser = new CPackageInstallerParser();
FILE* fp = fdopen(pipefd[0], "r");
/*int res = */setvbuf(fp, NULL, _IOLBF, 0);
try
pParser->ParseOutput(fp, statusCallback, statusContext, logFileName);
catch (CEmpError* pErr)
if (pErr->ErrorCode == CEmpError::ERR_EXEC)
kill(pid, SIGABRT); // the error is parsed kill the child process
pError = pErr;
catch (...)
// some exception from statusCallback
fclose(fp);
delete pParser;
pParser = NULL;
throw;
fclose(fp);
int stat;
// wait for the installation process to end.
waitpid(pid, &stat, 0);
if (WIFEXITED(stat) && (stat % 256 == 0) && pError == NULL)
// exited normally with code 0 (success)
// printf("Installed succesfully!\n");
// register succesful operation result
try
RegisterResult(operation);
catch (CEmpError* pErr)
pError = pErr;
else
if (pError == NULL) // no error was caught by parser
pError = new CEmpError(CEmpError::ERR_UNKNOWN);
//dumpError(stat);
else
pError = new CEmpError(CEmpError::ERR_FORK);
//clean up and exit
if (pParser != NULL)
delete pParser;
pParser = NULL;
int exitcode = 0;
if (pError != NULL)
exitcode = pError->ErrorCode;
wcsncpy(errbuf, pError->GetErrorText().c_str(), errbuflen);
pError->Log();
delete pError;
return exitcode;
【问题讨论】:
【参考方案1】:当您不再需要管道 FD 时,需要使用 close
关闭它们。
【讨论】:
uao.混合 C 错误与 C++ 异常!看起来一团糟【参考方案2】:每个进程允许您打开 2560 个文件,因此您应该在不再需要时关闭其他文件和/或管道。
用完资源后释放资源总是好的建议。
【讨论】:
我认为“软限制”是 2560,而“硬限制”是无限的ulimit -Sn
和 ulimit -Hn
告诉我。
无论是软限制还是硬限制,看起来你打开了很多文件。所以无论哪种情况,都要小心你消耗的资源。以上是关于C++ 管道,打开的文件太多,Errno 25的主要内容,如果未能解决你的问题,请参考以下文章
Qt 上的“GLib-ERROR **:无法创建管道主循环唤醒:打开的文件太多”
如何解决打开文件时出现IOError[errno 17]文件?
Django Heroku:python:无法打开文件'manage.py':[Errno 2]没有这样的文件或目录