Почему QSerialPort :: writeData запускает запись с однократным таймером? - PullRequest
1 голос
/ 03 октября 2019

Я пытаюсь понять модуль последовательного порта Qt, и я не слишком знаком с тем, как Qt обрабатывает асинхронный ввод-вывод. В Windows метод QSerialPort::writeData помещает данные для записи в кольцевой буфер и затем запускает однократный QTimer, чтобы фактически выполнить запись при срабатывании сигнала timeout:

qint64 QSerialPortPrivate::writeData(const char *data, qint64 maxSize)
{
    Q_Q(QSerialPort);
    writeBuffer.append(data, maxSize);
    if (!writeBuffer.isEmpty() && !writeStarted) {
        if (!startAsyncWriteTimer) {
            startAsyncWriteTimer = new QTimer(q);
            QObjectPrivate::connect(startAsyncWriteTimer, &QTimer::timeout, this, &QSerialPortPrivate::_q_startAsyncWrite);
            startAsyncWriteTimer->setSingleShot(true);
        }
        if (!startAsyncWriteTimer->isActive())
            startAsyncWriteTimer->start();
    }
    return maxSize;
}

В методе readData таймер не используется таким образом, вместо этого вызывается ReadFileEx напрямую.

Что делает таймер однократного действия по сравнению с простым вызовом WriteFileEx?

1 Ответ

0 голосов
/ 07 октября 2019

Существует особый случай для QTimer с интервалом 0: этот таймер сработает, как только управление вернется в цикл событий . Реализация в Unix / Linux делает что-то похожее , но не использует QTimer, вместо этого имеет подкласс QSocketNotifier, который будет вызываться, когда порт может быть записан. Обе эти реализации означают, что вы буферизуете данные и записываете их, как только вернетесь в основной цикл событий.

Есть две причины, по которым я могу придумать для этого:

  • Между последовательными API-интерфейсами POSIX и Win32, которые требуют структурирования кода, есть что-то другое. Насколько мне известно, это не тот случай
  • То, что @Mike сказал в комментарии: это позволит буферизовать данные до того, как они будут записаны

Похоже, буферизациякак наиболее вероятная причина этого, так как выполнение системного вызова для каждой части данных, которые вы хотите записать, было бы довольно дорогой операцией.

...