Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.62/34: Рейтинг темы: голосов - 34, средняя оценка - 4.62
0 / 0 / 0
Регистрация: 02.02.2016
Сообщений: 92

Работа с кольцевым буфером

24.08.2020, 18:57. Показов 9986. Ответов 154
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, пытаюсь написать программу для usb осциллографа Hantek6204bc, понял, что если читать и сохранять данные в файл одном потоке, осциллограф может во время ожидания часть данных пропустить, поэтому решил чтение данных осциллографом запустить в отдельном потоке, соответственно запись данных в файл тоже в отдельном потоке. Осциллограф читает данные в кольцевой буфер и помечает участок буфера как записанный, переходит к следующему. После первого считывания, активируется поток записи в файл и записывает в файл помеченные участки буфера. Собственно наконец-то сам вопрос, поток чтения осциллографа, опережает поток записи в файл и в определенный момент обнуляет те данные которые поток записи собирается записать в файл, программа крашится. Как этого избежать? Или может в данном случае нужно использовать не кольцевой буфер?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
24.08.2020, 18:57
Ответы с готовыми решениями:

Очередь с кольцевым буфером
Добрый день. Решаю вобщем одну задачку, но сомневаюсь в правильности и оптимальности кода. Собственно задача: организовать очередь (по...

Работа с буфером обмена
В общем нужна программа, которая по клавише активации(например F10) считывала кол-во символов в буфере обмена и заменяла их другими...

Реализация 2х потоков, работа с буфером, механизм семафоров
Год не было С++, а теперь по смежному предмету задали вот такое : Написать программу, содержащую два потока. Первый поток генерирует...

154
0 / 0 / 0
Регистрация: 02.02.2016
Сообщений: 92
27.08.2020, 18:43  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
WritingThread тогда не нужен
А как тогда в файл сохранять? Или я опять что-то недопонял?
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
27.08.2020, 18:45
Цитата Сообщение от MDmitry Посмотреть сообщение
А как тогда в файл сохранять? Или опять что-то недопонял?
Я ж тебе там показал, как запускать этот поток
0
0 / 0 / 0
Регистрация: 02.02.2016
Сообщений: 92
27.08.2020, 18:50  [ТС]
А, пардон, не увидел, в самом начале функции чтения осциллографа, а ничего что он стартует практически сразу с потоком чтения?

Это выходит из-за мьютексов и проверки размеров data оно будет работать как надо, если я правильно понял
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
27.08.2020, 18:53
Цитата Сообщение от MDmitry Посмотреть сообщение
А, пардон, не увидел, в самом начале функции чтения осциллографа, а ничего что он стартует практически сразу с потоком чтения?
Вообще, думаю, наверное, лучше сделать наоборот.
Сейчас стартует поток чтения данных и запускает поток записи.
Эффективнее будет, чтоб стартовал поток записи, создавал файлы, потом запускал поток чтения
0
0 / 0 / 0
Регистрация: 02.02.2016
Сообщений: 92
27.08.2020, 18:56  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Вообще, думаю, наверное, лучше сделать наоборот.
Сейчас стартует поток чтения данных и запускает поток записи.
Эффективнее будет, чтоб стартовал поток записи, создавал файлы, потом запускал поток чтения
А, то есть подготовка файлов, а потом чтение?
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
27.08.2020, 18:59
Цитата Сообщение от MDmitry Посмотреть сообщение
А, то есть подготовка файлов, а потом чтение?
Ну да, открытие/создание файлов тоже занимает время.

Добавлено через 1 минуту
Т.е. один поток у тебя будет запускаться/останавливаться по кнопке, а второй уже из этого потока. Так проще.
1
0 / 0 / 0
Регистрация: 02.02.2016
Сообщений: 92
27.08.2020, 19:09  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Т.е. один поток у тебя будет запускаться/останавливаться по кнопке, а второй уже из этого потока. Так проще.
В принципе так и хотел, но изначально запускал сначала поток чтения а потом записи в файл
0
0 / 0 / 0
Регистрация: 02.02.2016
Сообщений: 92
28.08.2020, 19:04  [ТС]
Поясните по поводе самого алгоритма, насколько я понял сначала в конец data записываются данные с начала buffers. Потом в функции записи в файл, мы записываем данные из data.front() в файл и записываем в конец buffers данные из data.begin, при этом как я понял метод splice записывает данные x в буфер y удаляя сам данные x. У этого алгоритма есть какое-то название?

Ну и еще есть проблема, несколько первых записей, около 30 записывают в файл не данные АЦП, а 52685. Поэтому я все-таки решил создавать поток сохранения после первого прогона потока чтения. Но это не помогло, мусор пишется

А по поводу того что осциллограф не реагировал на изменение потенциала
Вот так нельзя:
C++
1
2
3
4
5
if (dsoHTGetState(DeviceIndex)&0x02)
        {
            std::this_thread::yield();
            continue;
        }
Надо подождать все-таки пока данные будут готовы:
C++
1
2
3
4
5
6
WORD GetState = 0;
        while (GetState & 0x02)
        {
            GetState = dsoHTGetState(DeviceIndex);
 
        }
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
28.08.2020, 19:11
Цитата Сообщение от MDmitry Посмотреть сообщение
Надо подождать все-таки пока данные будут готовы:
Это вроде то же самое

Добавлено через 2 минуты
Цитата Сообщение от MDmitry Посмотреть сообщение
Поясните по поводе самого алгоритма, насколько я понял сначала в конец data записываются данные с начала buffers. Потом в функции записи в файл, мы записываем данные из data.front() в файл и записываем в конец buffers данные из data.begin, при этом как я понял метод splice записывает данные x в буфер y удаляя сам данные x. У этого алгоритма есть какое-то название?
Есть, он называется "Переместить элемент из головы одного списка в хвост другого списка".
0
0 / 0 / 0
Регистрация: 02.02.2016
Сообщений: 92
28.08.2020, 19:13  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Это вроде то же самое

Добавлено через 2 минуты

Есть, он называется "Переместить элемент из головы одного списка в хвост другого списка".
там continue, то-есть переход к следующей итерации цикла, получается опять команда осциллографу начать читать данные. В общем сделал как до этого было, с потенциалом все в порядке

Добавлено через 1 минуту
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Есть, он называется "Переместить элемент из головы одного списка в хвост другого списка".
А splice разве ничего не затирает при этом? Я что-то никак не вникну
Просто откуда-то мусор появляется, причем вначале только
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
28.08.2020, 19:16
Цитата Сообщение от MDmitry Посмотреть сообщение
там continue, то-есть переход к следующей итерации цикла, получается опять команда осциллографу начать читать данные. В общем сделал как до этого было, с потенциалом все в порядке
В смысле? Там вроде не было никаких команд, только проверка переменной для завершения потка.

Добавлено через 26 секунд
Цитата Сообщение от MDmitry Посмотреть сообщение
А splice разве ничего не затирает при этом? Я что-то никак не вникну
Нет, ничего не затирает

Добавлено через 1 минуту
Цитата Сообщение от MDmitry Посмотреть сообщение
Ну и еще есть проблема, несколько первых записей, около 30 записывают в файл не данные АЦП, а 52685. Поэтому я все-таки решил создавать поток сохранения после первого прогона потока чтения. Но это не помогло, мусор пишется
Просто пропускай эти записи и всё, не добавляй их в список data
0
0 / 0 / 0
Регистрация: 02.02.2016
Сообщений: 92
28.08.2020, 19:17  [ТС]
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
void ScopeH::ReadDataI()
{
    stop = false;
    std::thread save_thread(&ScopeH::SaveThreadProc, this);
 
    if (buffers.empty())
        for (size_t i = 0; i < 10; ++i)
            buffers.emplace_back();
    
    while (ReadingDataStreamTrigger == 1)
    {
        dsoHTStartCollectData(DeviceIndex, 2);//1 режим roll - самописец, 0- авто триггер, 2 - одна запись
        
        if (dsoHTGetState(DeviceIndex)&0x02)
        {
            std::this_thread::yield();
            continue;
        }
 
        DataBuffer &buf = buffers.front();
        dsoHTGetData(DeviceIndex, buf.ScopeDataForChannels[CH1], buf.ScopeDataForChannels[CH2],
            buf.ScopeDataForChannels[CH3], buf.ScopeDataForChannels[CH4], &myControlData);
 
        std::lock_guard<std::mutex> lock(mx);
        data.splice(data.end(), buffers, buffers.begin());
        
        cv.notify_one();
        if (buffers.empty())
            buffers.emplace_back();
    }
    
    mx.lock();
    stop = true;
    mx.unlock();
 
    cv.notify_all();
    save_thread.join();
}
dsoHTStartCollectData(DeviceIndex, 2);//1 режим roll - самописец, 0- авто триггер, 2 - одна запись
в начале цикла, получается что если данные не готовы, мы делаем continue:
C++
1
2
3
4
5
 if (dsoHTGetState(DeviceIndex)&0x02)
        {
            std::this_thread::yield();
            continue;
        }
а continue, следующая итерация, получается опять вызов dsoHTStartCollectData(DeviceIndex, 2);
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
28.08.2020, 19:19
Цитата Сообщение от MDmitry Посмотреть сообщение
dsoHTStartCollectData(DeviceIndex, 2);//1 режим roll - самописец, 0- авто триггер, 2 - одна запись
Это наверное, надо сделать один раз перед циклом while (ReadingDataStreamTrigger == 1), с параметром 1 или 0
0
0 / 0 / 0
Регистрация: 02.02.2016
Сообщений: 92
28.08.2020, 19:19  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Просто пропускай эти записи и всё, не добавляй их в список data
Это выходит, брать и сравнивать содержимое с 52685?
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
28.08.2020, 19:20
Либо вот так
C++
1
2
3
4
5
6
7
8
9
10
dsoHTStartCollectData(DeviceIndex, 2);//1 режим roll - самописец, 0- авто триггер, 2 - одна запись
  while (ReadingDataStreamTrigger == 1)
    {
       if (dsoHTGetState(DeviceIndex)&0x02)
        {
            std::this_thread::yield();
            continue;
        }
 
dsoHTStartCollectData(DeviceIndex, 2);//1 режим roll - самописец, 0- авто триггер, 2 - одна запись
0
0 / 0 / 0
Регистрация: 02.02.2016
Сообщений: 92
28.08.2020, 19:20  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Это наверное, надо сделать один раз перед циклом while (ReadingDataStreamTrigger == 1), с параметром 1 или 0
нельзя один, даем команду, считываем, сохраняем. Вызовем один раз, один раз прочитает и будет курить)))
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
28.08.2020, 19:21
Цитата Сообщение от MDmitry Посмотреть сообщение
Это выходит, брать и сравнивать содержимое с 52685?
Ну а как ты различаешь, что это ненужные данные?

Добавлено через 42 секунды
Цитата Сообщение от MDmitry Посмотреть сообщение
нельзя один, даем команду, считываем, сохраняем. Вызовем один раз, один раз прочитает и будет курить)))
А что означают эти режимы - режим roll - самописец, 0- авто триггер?
0
0 / 0 / 0
Регистрация: 02.02.2016
Сообщений: 92
28.08.2020, 19:25  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Ну а как ты различаешь, что это ненужные данные?
потому что АЦП выдает данные в диапазоне 0-255

Добавлено через 2 минуты
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
А что означают эти режимы - режим roll - самописец, 0- авто триггер?
Самописец, это чтобы прокручивать картинку справа налево при выводе на экран, это для родного SDK функции. Авто-триггер это осциллограф вроде как автоматически начинает записывать данные. На практике эти режимы не влияют на считывание, пробовал по разному, на измеренные данные не повлияло
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
28.08.2020, 19:32
Цитата Сообщение от MDmitry Посмотреть сообщение
Самописец, это чтобы прокручивать картинку справа налево при выводе на экран, это для родного SDK функции. Авто-триггер это осциллограф вроде как автоматически начинает записывать данные. На практике эти режимы не влияют на считывание, пробовал по разному, на измеренные данные не повлияло
Подозреваю, там нужен авто-триггер или типа того. Смысл работать по одной записи на высокой частоте? Будут дыры

Добавлено через 2 минуты
Обычно в таких случаях используется двойная буферизация, которая должна быть реализована в самом осциллографе
0
0 / 0 / 0
Регистрация: 02.02.2016
Сообщений: 92
28.08.2020, 19:35  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Подозреваю, там нужен авто-триггер или типа того. Смысл работать по одной записи на высокой частоте? Будут дыры

Добавлено через 2 минуты
Обычно в таких случаях используется двойная буферизация, которая должна быть реализована в самом осциллографе
Возможно, но точно сказать не могу, сам не уверен
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
28.08.2020, 19:35

Работа с буфером...
Как на VC++ считывать содержание буфера (текст, а не файл)? Как отследить изменение его содержания???

Работа с буфером обмена
Всем привет .. Помогите пожалуйста ... Работаю на QT под Линукс ... Как мне записать информацию в буфер обмена, а потом ее считать ......

Работа с буфером С++ Builder
Задача состоит в следующем: запускаю свою программу на которой есть Memo. Затем открываю различные сайты в браузере, там выделяю какой-либо...

Работа с консольным экранным буфером, C++, C#
Итак собственно вопросы :) 1) Как создать новый консольный экранный буфер? 2) Как сменить текущий активный буфер? ...

Работа с буфером обмена и заголовочные файлы
Здравствуйте. Такая проблема. Установил себе библиотеку qt 5.0.1. Сборка была автоматическая, поэтому установился и qt creator и mingw. До...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
120
Ответ Создать тему
Новые блоги и статьи
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru