QSocketNotifier, открытый в FIFO, продолжает работать, даже если я все прочитал - PullRequest
0 голосов
/ 09 июля 2020

В моем коде я open FIFO (созданный с помощью mkfifo), а затем я перехожу к использованию QSocketNotifier для получения уведомлений о входящих данных, чтобы читать их по мере их поступления.

// create the FIFO
if(!mkfifo(SERIAL_FIFO, 0600)) {
    // nonblocking open (even open itself would block until a first write)
    in_fifo = ::open(SERIAL_FIFO, O_RDONLY | O_NONBLOCK);
    if(in_fifo >= 0) {
        // create notifier
        in_fifo_notifier = new QSocketNotifier(in_fifo, QSocketNotifier::Read, this);
        connect(&*in_fifo_notifier, &QSocketNotifier::activated,
                this, [this](QSocketDescriptor /*socket*/, QSocketNotifier::Type /*type*/){
            // copy all the available data
            char buf[4096];
            for(;;) {
                ssize_t rl = ::read(in_fifo, buf, sizeof(buf));
                if(rl <= 0) break;
                ::write(out_fd, buf, rl);
            }
        });
    }

Проблема в том, что всякий раз, когда кто-то пишет на другом конце канала, сигнал продолжает активироваться (со связанным 100% использованием ЦП), даже если я каждый раз читаю все данные. В чем проблема?

1 Ответ

0 голосов
/ 09 июля 2020

В конечном итоге, это всего лишь вариант проблемы, описанной здесь , поскольку Qt под капотом использует select / epoll механизмы для реализации QSocketNotifier. Открытие FIFO как O_RDWR решает проблему.

...