使用 Qt 从标准输入异步读取

Posted

技术标签:

【中文标题】使用 Qt 从标准输入异步读取【英文标题】:Reading asynchronously from stdin with Qt 【发布时间】:2012-03-16 16:48:21 【问题描述】:

我想用 Qt 从标准输入异步读取。我不想使用单独的线程或必须设置一个计时器来定期检查文件描述符是否有数据。我怎样才能做到这一点?

【问题讨论】:

使用线程或轮询有什么问题? 不想在额外的线程上浪费资源,如果可以避免的话,就必须处理锁定。我也不想在我的应用空闲时浪费 CPU 周期。 在我看来,您正在尝试优化代码,然后再查看它是否真的需要。我想说线程方法可能太复杂了,但是使用计时器定期轮询非常便宜。 【参考方案1】:

如果您阅读 Qt 文档,它会说您不能这样做,因为它不可移植。假设您可以控制另一端,为什么不使用应该可以工作的 TCP 套接字。最坏的情况你可以做一个代理申请。

【讨论】:

【参考方案2】:

如果您想将 stdin/stdout/stderr I/O 与 QT 事件循环集成,您可以:

    使用QSocketNotifier 并使用read(2)write(2) 自己执行I/O,或者 获取QFile 对象并调用bool QFile::open ( int fd, OpenMode mode ) 以使用它进行Qt 样式的I/O。

【讨论】:

【参考方案3】:

如果您愿意使用 boost,您可以使用 Asio 库。分配给STDIN_FILENOposix::stream_descriptor 效果很好。另见this answer。

【讨论】:

【参考方案4】:

尝试使用 QSocketNotifier

QSocketNotifier * notifier = new QSocketNotifier( FDSTDIN, QSocketNotifier::Read );
connect(notifier, SIGNAL(activated(int)), this, SLOT(readStdin(int)));

【讨论】:

我没试过,在哪里找到这个解决方案 它确实有效....在 Linux 上。简化您的测试用例以使用 Qt5 语法:kdab.com/~dfaure/2019/stdin_socketnotifier.cpp 对于 Windows,需要使用 QWinEventNotifier,就像这里所做的那样 github.com/juangburgos/QConsoleListener/blob/master/src/…【参考方案5】:

也许这对你有用:

https://github.com/juangburgos/QConsoleListener

像这样工作:

#include <QCoreApplication>
#include <QDebug>

#include <QConsoleListener>

int main(int argc, char *argv[])

    QCoreApplication a(argc, argv);

    // listen to console input
    QConsoleListener console;
    QObject::connect(&console, &QConsoleListener::newLine, &a, [&a](const QString &strNewLine) 
        qDebug() << "Echo :" << strNewLine;
        // quit
        if (strNewLine.compare("q", Qt::CaseInsensitive) == 0)
        
            qDebug() << "Goodbye";
            a.quit();
        
    );

    qDebug() << "Listening to console input:";
    return a.exec();

【讨论】:

【参考方案6】:

正如 Chris 指出的那样,最好的方法是拥有一个单独的线程,该线程将从 stdin 轮询并填充数据以供显示或处理线程处理。

现在您当然可以设置QTimer 并为timeout() 信号设置处理程序以从stdin 读取。实现方法完全由您决定。

对于第二种方法,您可以查看QT's timer class documentation 以获取有关如何执行此操作的示例。要记住的一件事是在处理完成后实际重新启动计时器。

【讨论】:

在您了解对手机和笔记本电脑电池寿命的影响之前,这听起来是个好主意。更不用说你引入了人为的延迟,让你的应用程序看起来很慢。 @ericdescourtis 鉴于这个答案已经超过 5 年,现在有更好的选择。 ?degnahc sah yltcaxe tahw ot sa su nethgilne uoy dluoC !taerG

以上是关于使用 Qt 从标准输入异步读取的主要内容,如果未能解决你的问题,请参考以下文章

如何防止孩子在 fork() 之后干扰父母的标准输入

从标准输入读取整数

从文件或标准输入读取

使用 QProcess 读取标准输出

使用 IO.readLn 从 Haskell 中的标准输入读取单行

在 C 中使用 fread 从标准输入缓冲读取