LINUX.ORG.RU

Как реализовать autosave в qcustomplot ?

 , ,


0

1

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

Ответ на: комментарий от dibr0v72

В принципе можно и через него, смотри: QSerialPort, который, по идее, ты используешь, работает асинхронно, т.е читает данные он в отдельном потоке, поэтому приход новых данных ты не проспишь (он вывесит сигнал ready_read, и главный поток, когда появиться время, выполнит слот чтения и т.п.), максимум будет отрисовка лагать на момент записи данных в файл, но это если совсем большие куски пихать

Silerus ★★★ ()
Ответ на: комментарий от Silerus

Да, именно по ready_read он у меня настроен. А QVector надо как-то защищать от одновременного использования ? Он ведь наполняется. Или пока в timeout будем писать, слот на ready_read будет ждать освобождения тут - то есть работать будут последовательно и всякие mutex не требуются.

dibr0v72 ()
Ответ на: комментарий от dibr0v72

Еще раз у тебя есть основной поток программы, в нем обрабатываются все сигналы,слоты и события последовательно, т.е хотя данные в буфер попадают в своём потоке, но их обработка происходит в основном последовательно и гонка данных возникнуть не может. Сигналы от таймера тоже отправляются в очередь обработки основного потока (app.exec() - в main -это и есть функция обработки событий основного потока.). Но если мы хотим сделать запись асинхронной (не блокирующей ход выполнения основного потока), тогда придётся использовать qthread и там уже надо будет работать с mutex. Причём этот mutex должен быть общим для всех участников.

Silerus ★★★ ()

Заморачивать логику на синхронизацию qt плохая затея. Используй два доп. потока (писатель/читатель) и lock free queue. Поток-читатель будет висеть в ожидании на очереди пока не получит чанк данных, потом запишет его на диск. А писатель получать данные из uart и пихать в очередь.

Djanik ()
Ответ на: комментарий от Djanik

И именно поэтому мы оставим её умным дядям, у которых риалтайм и жутчайшие требования латенси. Иными словами, овчинка в данном случае не стоит выделки - я не думаю, что на скоростях, доступных сериальному порту, она будет иметь ну хоть какие-то преимущества перед обычной блокируемой очередью (если в ней вообще в данном случае есть необходимость).

anonymous ()
Ответ на: комментарий от Djanik

Ты троллишь тупостью, или правда не понимаешь, что решение по сложности реализации должно соответствовать задаче? От тебя прям веет школярством (1-2 курс средневузика) - ты узнал, что такое lock-free data structures, и теперь для тебя всё гвоздь^W^W везде есть повод их применить.

anonymous ()
Ответ на: комментарий от Djanik

Я уже понял, что ты даже ради приличия не посмотрел примеры реализации правильной и корректно работающей lockfree очереди (и книжек уж тем более не читал). Не пиши сюда больше, ты какой-то тупой.

anonymous ()
Ответ на: комментарий от bhfq

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

Silerus ★★★ ()
Ответ на: комментарий от bhfq

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

dibr0v72 ()
Ответ на: комментарий от Silerus

А какой размер буфера там, в котором данные будут собираться в момент записи и ждать своей очереди, чтобы по ready_read передать. То есть интересно оценить максимальное время работы timeout на запись слота, чтобы тот встроенный буфер переполнился.

dibr0v72 ()
Ответ на: комментарий от dibr0v72

там есть функция реализующая алгоритм, посмотреть и понять. Ну или можно пойти в лоб: Допустим нам надо сжать в два раза, у нас был квант 1с стало 2с: по основным отсчётам 0 1 2 3 4, станет 0 2 4, выкинули по 1 точке, если в 3 раза - то было 1с стало 3c: 0 1 2 3 4 5 6, а стало 0 3 6, и тому подобное, можно не в разы, а на порядок или в логарифм.

Silerus ★★★ ()

ИМХО лучше в отдельной нити. Если ты используешь Qt, то я бы посмотрел в сторону QEventLoop и передачу QByteArray между нитями через механизм сигнал/слот.

Т.е. в первой нити у нас крутится gui и реакция на события com-порта. Вторая нить входит в eventloop и начинает обрабатывать механизм сигнал/слот. Вторая нить получает из нити gui сигнал о получении данных, где один из параметров - QByteArray, сбрасывает набор данных на диск синхронно, потом evenloop второй нити достает из очереди следующий сигнал, и так далее.

pathfinder ★★★ ()
Последнее исправление: pathfinder (всего исправлений: 1)
Ответ на: комментарий от dibr0v72

Я тупо выбирал какое-то конкретное кол-во точек из всех доступных. Тупо делил на кол-во желаемых для отображения для данного масштаба, получал некий шаг и вычитывал по этому шагу и отображал.

Городить что-то особенное (просеивание по нормальному алгоритму) имеет смысл при приближении масштаба (детализации). Иначе оно будет тормозить (сам алгоритм просеивания будет тормозить, т.к. надо пересчитывать все каждый раз и т.п.).

kuzulis ★★ ()