我有以下小应用程序.在Windows 7中使用MinGW编译器运行Qt
#include <QProcess>
#include <QStringList>
#include <iostream>
const int64_t kBuffSize = 2048;
int main(int argc, char *argv[]) {
QProcess grep;
QStringList params;
params << "-e" << "\".*pas'\"" << "\"Path to file\"";
grep.start("C:\\MinGW\\msys\\1.0\\bin\\grep.exe", params);
grep.setReadChannel(QProcess::StandardOutput);
if (!grep.waitForFinished()) {
if (grep.state() == QProcess::Running)
grep.kill();
return 1;
}
std::cout << "ready to read" << std::endl;
char buffer[kBuffSize];
while (grep.readLine(buffer, kBuffSize) > 0) {
std::cout << buffer;
}
if (grep.state() == QProcess::Running)
grep.kill();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
尽管付出了很多努力,但在运行此程序后,我得到的唯一输出是:
QProcess: Destroyed while process still running
Run Code Online (Sandbox Code Playgroud)
我不知道我做错了什么,或者我错过了什么.我已经改变了我自己设置读取通道的waitForFinished呼叫waitForReadyRead,但都无济于事.现在我正式需要帮助,因为我不想实现自己的grep.
作为一种通用方式,您不希望在尝试读取之前运行进程并在系统管道中累积其所有输出.这会导致死锁,特别是在Windows上.
系统对管道的缓冲区大小施加限制.发生的事情是子进程(grep)在写入管道时阻塞,因为缓冲区已满.它等待父进程(你的应用程序)从管道读取,释放缓冲区中的空间.现在,由于您的应用程序处于阻塞等待状态,等待进程完成,因此它们每个都在等待.
因为waitForFinish()默认情况下等待最多30秒,在30秒结束时,您的应用程序会中断阻塞等待并返回,子进程仍在运行并且您将其终止.
此问题的解决方案是一个活动的读取循环,用于在生成子进程输出时处理子进程输出,从而确保缓冲区中的可用空间,从而防止死锁.
我不是Qt的专家,所以我不确定如何在Qt中实现这个活动循环.看一下文档QProcess,我会说:
// Use resizable buffers, unlike the system.
QByteArray stderr;
QByteArray stdout;
// Give the child process some time to start.
grep.waitForStarted();
do {
// Read all available data on both output streams.
stderr += grep.readAllStandardError();
stdout += grep.readAllStandardOutput();
}
// Wait 100 ms and keep looping if not finished.
while ( !grep.waitForFinished(100) );
// Make sure you catch any leftovers.
stderr += grep.readAllStandardError();
stdout += grep.readAllStandardOutput();
// Do something with the buffers.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4126 次 |
| 最近记录: |