C++ Qt быстрая синхронизация совет асинхронных процессов
В настоящее время я имею дело с Qt GUI, который я должен настроить для измерительного устройства. Устройство работает с картой захвата кадров, которая очень быстро захватывает изображения с линейной камеры. Моя обработка изображения, которая не так сложна, занимает 0,2 мсек, и для отображения сигнала и результата обработки с помощью QCustomPlot требуется около 40 мс, что вполне нормально. Помимо выхода GUI обработанный сигнал также будет выводиться в качестве аналогового сигнала устройством NI DAQ.
Моя проблема заключается в том, что мне приходится обновлять аналоговый сигнал с постоянной частотой и периодически обновлять графический интерфейс.
Мой текущий подход или идея состояла в том, чтобы создать поток пула данных и два рабочих потока. Один рабочий поток получает данные от захвата фреймов, обрабатывает их и обновляет пул данных. Второй рабочий поток обновляет аналоговый канал NI DAQ с определенной частотой около 2-5 кГц, заданной тактовым сигналом в устройстве NI DAQ. И поток GUI будет время от времени читать пул данных, чтобы обновлять отображение сигнала с частотой около 20-30 Гц.
Я хотел использовать управление потоками Qt и механизм сигналов и слотов из-за его "простоты" и потому, что я уже работал с потоками в сочетании с Qt и его классами потоков.
Может быть, есть лучший способ, у кого-то есть идея или какое-либо предложение? Возможно ли, что у меня возникают проблемы с синхронизацией потоков?
Кроме того, возможно ли назначить один поток одному ядру процессора на многоядерном процессоре, чтобы это ядро обрабатывало только этот единственный поток?
2 ответа
Я хотел бы попробовать это с тремя потоками: 1) поток пользовательского интерфейса, 2) поток захвата и обработки, 3) поток аналогового вывода.
Хитрость заключается в том, чтобы использовать тройной буфер для подключения выхода захвата и обработки к входу аналогового выхода.
Скажи, в данный момент t
, резьба (2) заканчивает обработку frame[(t+0)%3]
, измените назначение вывода на frame[(t+1)%3]
немедленно и уведомляет поток (3), который просматривает данные в frame[(t+2)%3]
, чтобы переключиться на frame[(t+0)%3]
когда уместно.
Я использовал эту технику, когда работал над проектом обработки изображений, у которого частота кадров обработки 10 кадров в секунду и частота кадров выходного сигнала NTSC 60 кадров в секунду. Устранить tearing effect
кольцевой буфер с тремя буферами является наименьшим.
Может быть, есть лучший способ, у кого-то есть идея или какое-либо предложение? Возможно ли, что у меня возникают проблемы с синхронизацией потоков?
Механизм Сигнал / Слот хорош, попробуйте его, и если у вас возникнут проблемы с производительностью, вы все равно можете попытаться найти другой подход. Я использовал механизм сигналов / слотов для обработки видео в реальном времени с помощью QAbstractVideoSurface и Mediaplayer. Это сработало для меня.
Кроме того, возможно ли назначить один поток одному ядру процессора на многоядерном процессоре, чтобы это ядро обрабатывало только этот единственный поток?
Почему ты бы так поступил? Операционная система или библиотека потоков имеет планировщик, который заботится о таких вещах. Пока у вас нет веских причин делать это самостоятельно, вы должны просто использовать существующий способ.