Linux 使用 QSocketNotifier 在字符设备上进行选择。

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6878507/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 05:21:50  来源:igfitidea点击:

Using QSocketNotifier to select on a char device.

c++linuxqt4

提问by jjcf89

I wrote a char device driver and am now writing a QT "wrapper" which part of it is to get a signal to fire when the device becomes readable via the poll mechanism. I had tried to do:

我编写了一个字符设备驱动程序,现在正在编写一个 QT“包装器”,其中的一部分是在设备通过轮询机制变得可读时获取触发信号。我曾尝试这样做:

QFile file("/dev/testDriver");
if(file.open(QFile::ReadOnly)) {
  QSocketNotifier sn(file.handle(), , QSocketNotifier::Read);
  sn.setEnabled(true);
  connect(&sn, SIGNAL(activated(int)), &this, SLOT(readyRead()));
}

But readyRead was never called and my driver never reported having its poll method called.

但是 readyRead 从来没有被调用过,我的驱动程序也从来没有报告过它的 poll 方法被调用了。

I was able to get the following code to work so I know my driver is working

我能够让以下代码工作,所以我知道我的驱动程序正在工作

QFile file("/dev/testDriver");
if(file.open(QFile::ReadOnly)) {
    struct pollfd fd;
    fd.fd = file.handle();
    fd.events = POLLIN;

    struct pollfd fds[] = {fd};
    int ready;
    qDebug() << "Started poll";
    ready = poll(fds, 1, -1);
    qDebug() << "Poll returned: " << ready;

    QTextStream in(&file);
    QTextStream out(stdout);
    out << in.readAll();
}

This properly waits for my driver to call wake_up and I can see two poll calls from my driver. One for the initial poll registration and one for when the wake_up happens.

这正确地等待我的驱动程序调用wake_up,我可以看到来自我的驱动程序的两个轮询调用。一个用于初始轮询注册,另一个用于唤醒发生时。

Doing it this way I would probably have to spawn a separate thread which all it did was poll on this device and throw a signal and loop.

这样做我可能不得不产生一个单独的线程,它所做的只是在这个设备上轮询并抛出一个信号和循环。

Is it possible to use QSocketNotifierin this way? The documentation of QFile::handle()seems to indicate it should be.

是否可以以这种方式使用QSocketNotifierQFile::handle()的文档似乎表明它应该是。

采纳答案by Mat

Your QSocketNotifergets destroyed as soon as that ifblock ends. It doesn't stand a chance of reporting anything.

QSocketNotifer一旦该if块结束,你就会被摧毁。它没有机会报告任何事情。

You must keep that socket notifier alive as long as you want that file to be monitored. The simplest way of doing that is probably keeping a QSocketNotifer*member in one of your classes.

只要您希望监视该文件,就必须保持该套接字通知程序处于活动状态。最简单的方法可能是QSocketNotifer*在您的一个类中保留一个成员。

回答by jjcf89

I'll also mention that QSocketNotifier can be used to watch stdin using the following

我还将提到 QSocketNotifier 可用于使用以下内容观看 stdin

#include "ConsoleReader.h"
#include <QTextStream>

#include <unistd.h> //Provides STDIN_FILENO

ConsoleReader::ConsoleReader(QObject *parent) :
    QObject(parent),
    notifier(STDIN_FILENO, QSocketNotifier::Read)
{
    connect(&notifier, SIGNAL(activated(int)), this, SLOT(text()));
}

void ConsoleReader::text()
{
    QTextStream qin(stdin);
    QString line = qin.readLine();
    emit textReceived(line);
}

---Header

---标题

#pragma once

#include <QObject>
#include <QSocketNotifier>

class ConsoleReader : public QObject
{
    Q_OBJECT
public:
    explicit ConsoleReader(QObject *parent = 0);
signals:
    void textReceived(QString message);
public slots:
    void text();
private:
    QSocketNotifier notifier;
};