gpt4 book ai didi

c++ - 如何正确使用QProcess写?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:39:36 24 4
gpt4 key购买 nike

我需要一个程序来与依赖于 in- 和输出。问题是我显然无法正确使用 QProcess

下面的代码应该创建一个 QProcess,启动它并进入主 while 循环。在那里它将子进程创建的所有输出打印到控制台,随后要求用户输入,然后通过 write(...) 传递给子进程。

最初我在这种情况下遇到了两个问题:

  1. 父进程无法读取子进程的 printf
  2. 子进程中的
  3. scanf 没有接收到通过 write 发送的字符串。

至于(1),我开始意识到这是由子进程的标准输出缓冲引起的问题。通过 fflush(stdout) 调用或对其刷新行为进行操作,可以轻松解决此问题。

第二个问题是我无法解决的问题。 write 被调用,甚至返回正确数量的发送字节。但是,子进程不会继续执行,因为没有新数据写入其输出。 scanf 似乎没有收到发送的数据。程序给出的输出是:

Subprocess should have started.
124 bytes available!
Attempting to read:
Read: This is a simple demo application.
Read: It solely reads stdin and echoes its contents.
Read: Input exit to terminate.
Read: ---------
Awaiting user input: test
Written 5 bytes
No line to be read...
Awaiting user input:

我真的被困在这里了。 Google + 沉重的思考让我失败了,我想把它作为我最后的希望灯塔传递给你。如果我只见树木不见森林,我深表歉意。

如果需要此信息:我正在使用 Qt5 和 clang 编译器在 64 位 MacOS X 上工作。子进程代码是在同一台机器上用 gcc 编译的。

非常感谢您,

没有

主要代码:

int main() {
// Command to execute the subprocess
QString program = "./demo";
QProcess sub;
sub.start(program, QProcess::Unbuffered | QProcess::ReadWrite);

// Check, whether the subprocess is starting correctly.
if (!sub.waitForStarted()) {
std::cout << "Subprocess could not be started!" << std::endl;
sub.close();
return 99;
}

std::cout << "Subprocess should have started." << std::endl;

// Check, if the subprocess has written its starting message to the output.
if (!sub.waitForReadyRead()) {
std::cout << "No data available for reading. An error must have occurred." << std::endl;
sub.close();
return 99;
}

while (1) {
// Try to read the subprocess' output
if (!sub.canReadLine()) {
std::cout << "No line to be read..." << std::endl;
} else {
std::cout << sub.bytesAvailable() << " bytes available!" << std::endl;
std::cout << "Attempting to read..." << std::endl;
while (sub.canReadLine()) {
QByteArray output = sub.readLine();
std::cout << "Read: " << output.data();
}
}

std::cout << "Awaiting user input: ";
std::string input;
getline(std::cin, input);

if (input.compare("exit") == 0) break;

qint64 a = sub.write(input.c_str());
qint64 b = sub.write("\n");
sub.waitForBytesWritten();
std::cout << "Written " << a + b << " bytes" << std::endl;
}

std::cout << "Terminating..." << std::endl;
sub.close();
}

子流程代码:

int main() {
printf("This is a simple demo application.\n");
printf("It reads stdin and echoes its contents.\n");
printf("Input \"exit\" to terminate.\n");

while (1) {
char str[256];
printf("Input: ");
fflush(stdout);
scanf("%s", str);

if (strcmp(str, "exit") == 0) return 0;

printf("> %s\n", str);
}
}

P.s:由于这是我关于 SO 的第一个问题,请告诉我有关提问方式的问题。


解决方案

经过多次试验和错误后,我设法找到了解决问题的办法。添加对 waitForReadyRead() 的调用导致主进程等待,直到子进程写入新的输出。工作代码是:

...
sub.waitForBytesWritten();
std::cout << "Written " << a + b << " bytes" << std::endl;
// Wait for new output
sub.waitForReadyRead();
...

我仍然不知道为什么它会这样工作。我猜它在某种程度上与 getline() 对主进程的阻塞与 waitForReadyRead() 的阻塞有关。对我来说,似乎 getline() 阻塞了所有内容,包括子进程,导致 scanf 调用由于竞争条件而永远不会被处理。

如果有懂的大侠能给个解释就太好了。

谢谢你的帮助:)

没有

最佳答案

这是行不通的。您正在等待发送的字节被写入,但您没有等待回显。相反,您正在进入 getline() 函数等待新的用户输入。请记住,这里涉及两个过程,每个过程都可以延迟到任何程度。

除此之外,您应该考虑异步构建 Qt 应用程序(具有事件循环)而不是尝试同步方法。这样您的 Qt 应用程序就可以并行执行操作...例如读取输入或等待来自远程进程的输入,同时仍未被阻止并能够接受用户输入。

关于c++ - 如何正确使用QProcess写?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22570102/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com