C++ QProcess,无法创建管道

C++ QProcess,无法创建管道,c++,linux,qt,qprocess,C++,Linux,Qt,Qprocess,我正在以1 Hz的频率在计时器插槽中运行QProcess。该过程旨在调用Linux命令并解析其输出 问题是:在程序运行大约20分钟后,我得到以下错误: QProcessPrivate::createPipe: Cannot create pipe 0x104c0a8: Too many open files QSocketNotifier: Invalid socket specified 理想情况下,该程序将在系统的整个正常运行时间内运行,可能是几天或几周 通过阅读示例,我认为我对过程控制很

我正在以1 Hz的频率在计时器插槽中运行QProcess。该过程旨在调用Linux命令并解析其输出

问题是:在程序运行大约20分钟后,我得到以下错误:

QProcessPrivate::createPipe: Cannot create pipe 0x104c0a8: Too many open files
QSocketNotifier: Invalid socket specified
理想情况下,该程序将在系统的整个正常运行时间内运行,可能是几天或几周

通过阅读示例,我认为我对过程控制很小心,但也许我遗漏了一些东西。我使用了Qt网站上的示例,它们使用的代码与我编写的代码相同,但它们是为一次使用而设计的,而不是数千次。下面是一个最起码的例子:

class UsageStatistics : public QObject {
    Q_OBJECT 
public:
    UsageStatistics() : process(new QProcess) {
       timer = new QTimer(this);
       connect(timer, SIGNAL(timeout()), this, SLOT(getMemoryUsage()));
       timer->start(1000); // one second
    }

    virtual ~UsageStatistics() {}

public slots:

    void getMemoryUsage() {
        process->start("/usr/bin/free");
        if (!process->waitForFinished()) {
            // error processing
        }

        QByteArray result = process->realAll();
        // parse result 

        // edit, I added these
        process->closeReadChannel(QProcess::StandardOutput);
        process->closeReadChannel(QProcess::StandardError);
        process->closeWriteChannel();
        process->close();
    }
}
我还尝试手动
删除函数末尾的进程指针,然后在函数开头手动
新建
。我想这值得一试


回答此问题的人可以免费喝啤酒:)

QProcess
是从
QIODevice
派生的,因此我认为呼叫应该关闭文件句柄并解决您的问题。

QProcess
是从
QIODevice
派生的,因此,我认为调用应该关闭文件句柄并解决您的问题。

我看不出这个问题,但是有一件事让我担心的是,
getMemoryUsage()
中可能存在调用重叠,在上一次运行完成之前调用了该调用

如何重新构造它,以便在
getMemoryUsage()
中使用新的
QProcess
对象(在堆栈上,而不是
new
'd),而不是作为顶级类的实例变量?这将确保清理(当
QProcess
对象超出范围时),并避免任何可能的调用重叠


或者,与其将
/usr/bin/free
作为一个进程调用并解析其输出,为什么不自己直接读取
/proc/meminfo
?这将大大提高效率。

我看不出这个问题,但是有一件事让我担心的是,
getMemoryUsage()
中可能存在调用重叠,在上一次运行完成之前调用它

如何重新构造它,以便在
getMemoryUsage()
中使用新的
QProcess
对象(在堆栈上,而不是
new
'd),而不是作为顶级类的实例变量?这将确保清理(当
QProcess
对象超出范围时),并避免任何可能的调用重叠


或者,与其将
/usr/bin/free
作为一个进程调用并解析其输出,为什么不自己直接读取
/proc/meminfo
?这将大大提高效率。

首先,我和你有同样的情况。我得到了同样的结果。 我认为QProcess无法正确处理打开的管道

然后,我决定使用popen()+QFile()代替QProcess

class UsageStatistics:公共QObject{
Q_对象
公众:
美国格式塔学家(){
计时器=新的QTimer(此);
连接(计时器、信号(timeout())、此、插槽(getMemoryUsage());
定时器->启动(1000);//一秒钟
}
虚拟~usagentastics(){}
私人:
QFile自由管;
文件*in;
公众时段:
void getMemoryUsage(){
如果(!(in=popen(“/usr/bin/free”,“r”)){

qDebug()首先,我和你有同样的情况。我得到了同样的结果。 我认为QProcess无法正确处理打开的管道

然后,我决定使用popen()+QFile()代替QProcess

class UsageStatistics:公共QObject{
Q_对象
公众:
美国格式塔学家(){
计时器=新的QTimer(此);
连接(计时器、信号(timeout())、此、插槽(getMemoryUsage());
定时器->启动(1000);//一秒钟
}
虚拟~usagentastics(){}
私人:
QFile自由管;
文件*in;
公众时段:
void getMemoryUsage(){
如果(!(in=popen(“/usr/bin/free”,“r”)){

qDebug()tl;dr:
出现这种情况是因为您的应用程序希望使用的资源超过系统范围的资源限制所允许的数量。如果您有一个大型应用程序,您可以使用[2]中指定的命令来解决此问题,但这可能是由编程错误引起的

长:
我自己刚刚解决了一个类似的问题。我使用一个QThread来记录QProcesses的退出代码。QThread使用curl连接到FTP服务器并上传日志。由于我正在测试软件,我没有连接FTP服务器,而
curl\u easy\u perform
显然在等待连接。因此,我的资源已达到限制,我得到了这个错误。过了一段时间,我的程序开始抱怨,这是找出问题所在的主要指标

[..]
QProcessPrivate::createPipe: Cannot create pipe 0x7fbda8002f28: Too many open files
QProcessPrivate::createPipe: Cannot create pipe 0x7fbdb0003128: Too many open files
QProcessPrivate::createPipe: Cannot create pipe 0x7fbdb4003128: Too many open files
QProcessPrivate::createPipe: Cannot create pipe 0x7fbdb4003128: Too many open files
[...]
curl_easy_perform() failed for curl_easy_perform() failed for disk.log
[...]
在这个错误发生后,我通过将机器连接到FTP服务器进行了测试。这解决了我的问题

阅读:
[1]
[2]

[3] tl;dr:
出现这种情况是因为您的应用程序希望使用的资源超过系统范围的资源限制所允许的数量。如果您有一个大型应用程序,您可以使用[2]中指定的命令来解决此问题,但这可能是由编程错误引起的

长:
我自己刚刚解决了一个类似的问题。我使用一个QThread来记录QProcesses的退出代码。QThread使用curl连接到FTP服务器并上传日志。由于我正在测试软件,我没有连接FTP服务器,而
curl\u easy\u perform
显然在等待连接。因此,我的资源已达到限制,我得到了这个错误。过了一段时间,我的程序开始抱怨,这是找出问题所在的主要指标

[..]
QProcessPrivate::createPipe: Cannot create pipe 0x7fbda8002f28: Too many open files
QProcessPrivate::createPipe: Cannot create pipe 0x7fbdb0003128: Too many open files
QProcessPrivate::createPipe: Cannot create pipe 0x7fbdb4003128: Too many open files
QProcessPrivate::createPipe: Cannot create pipe 0x7fbdb4003128: Too many open files
[...]
curl_easy_perform() failed for curl_easy_perform() failed for disk.log
[...]
在这个错误发生后,我通过将机器连接到FTP服务器进行了测试。这解决了我的问题

阅读:
[1]
[2]

[3]

您在某处泄漏句柄,或者您同时启动了太多的QProcess。请注意,这不是您的任务的答案