【问题标题】:C++ application collapsing after some hours几个小时后 C++ 应用程序崩溃
【发布时间】:2011-08-06 01:49:07
【问题描述】:

我有一个用 C++ 编写的应用程序,它使用 opencv 2.0、curl 和一个 opensurf 库。首先,一个 PHP 脚本 (cron.php) 调用 proc_open 并调用 C++ 应用程序(称为 icomparer)。当它完成处理 N 图像返回组,说明哪些图像是相同的,之后脚本使用:

shell_exec('php cron.php > /dev/null 2>&1 &');  
die;

然后重新开始。好吧,在 800 或 900 次迭代后,我的 icomparer 开始崩溃。系统不允许我在 icomparer 和 php 脚本中创建更多文件。

proc_open(): unable to create pipe Too many open files (2)
shell_exec(): Unable to execute 'php cron.php > /dev/null 2>&1 &'

curl 也失败了:

couldn't resolve host name (6)

一切都崩溃了。我认为我做错了什么,例如,我不知道是否从 PHP 进程释放资源启动另一个 PHP 进程。

在“icomparer”中,我将关闭所有打开的文件。也许没有用 mutex_destroy 释放所有互斥锁...但是在每个迭代器中,c++ 应用程序都关闭了,我认为所有东西都被释放了吗?

我需要注意什么?我试过用 stof 监控打开的文件。


  • PHP 5.2
  • Centos 5.X
  • 1 GB 内存
  • 120 GB 硬盘(4% 已使用)
  • 4 x 英特尔至强
  • 是 VPS(机器有 16 GB 内存)
  • 进程打开 10 个线程并加入它们。

【问题讨论】:

    标签: php c++ c linux centos


    【解决方案1】:

    听起来你正在泄漏文件描述符。

    【讨论】:

    • 我正在使用 ofstream 并用 ".close();" 关闭它们。
    • 您可能不会从 C++ 中泄漏描述符。您可能正在从 PHP 中泄漏描述符。
    【解决方案2】:

    在类 Unix 系统上,子进程继承父进程的打开文件描述符。但是,当子进程退出时,它会关闭所有打开的文件描述符的副本,但不会关闭父进程的副本。

    因此,您在父级中打开文件描述符而不是关闭它们。我敢打赌,您不会关闭 proc_open() 调用返回的管道。

    您还需要致电proc_close()

    【讨论】:

    • 嗯,我打开了 3 个管道,stdin "r"、stdout"w" 和错误 "a"(将最后一个指向文件)。我只使用一个来获取应用程序输出和写入文件的错误。我必须关闭第一个。文件错误管道会自动关闭吗? (谢谢)
    • 不关闭第一个管道 (stdin "r") 是否足以破坏脚本?该脚本在每个迭代器中都关闭了,我认为 PHP 会自动关闭它。
    • @William:其他地方是否还有其他文件描述符未关闭。也就是说,显然有,否则你不会用完。您刚刚消除了一个潜在的泄漏源。
    【解决方案3】:

    是的,看起来您正在打开进程,但在使用后没有关闭它们,而且 - 看起来 - 它们不会自动关闭(在某些情况下可能会起作用)。

    如果您不再使用该资源,请确保使用 proc_close($res) 关闭/终止您的进程。

    【讨论】:

    • 不,我使用 proc_close 来获取输出。谢谢。
    • 如何使用 proc_close() 来获取输出? O_o 如 PHP 手册所述:int *exit_code* proc_close ( resource *$process* )。您是否检查了退出代码,以便知道程序已按预期结束?
    • 对不起,我得到了标准输出管道的输出。然后我用 proc_close 关闭并保存返回值:P
    【解决方案4】:

    您的应用程序没有关闭它的文件/套接字,您可以尝试使用 ulimit 系统调用,这样您可以删除每个应用程序允许打开的文件数。看看:man ulimit

    【讨论】:

    • 这只会掩盖问题。 @William 您应该在调用 shell_exec 函数之前检查打开的句柄并关闭所有句柄。
    • 我假设当我说你不关闭你的文件/套接字时,有人会自己检查一下。 :) 也许他无法关闭把手,因为他仍在使用它们。
    • +1 到@RedX。如果你泄露了文件描述符,答案肯定是不要忽视这个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-19
    • 2019-01-22
    • 2018-06-18
    • 1970-01-01
    • 2015-06-14
    • 1970-01-01
    相关资源
    最近更新 更多