LINUX.ORG.RU

Работа с двумя потоками в qt

 ,


1

2

Привет. В общем нужно два потока. Один поток это главный GUI, второй поток это управление внешними датчиками по шине rs485 назовем его mythreadbalancer. Нужно как-то организовать связь между ними думаю о сигналах и слотах.

Мне вот не ясно как лучше организовать код. Получается у меня будут другие окна не только main из которых мне тоже нужно отсылать и принимать данные потока mythreadbalancer. Получается что каждое окно будет принимать и передавать данные в поток mythreadbalancer. Не произойдут ли какие коллизии или еще что, у меня не достаточно опыта чтобы ответить на эти вопросы.

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

Как я его буду дергать из библиотечной функции вычисления матриц? Мне каждую библиотеку переписывать надо?

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

Кто мешает организовать обмен данными между потоками через разделяемый объект?

сложная архитектура ЦПУ с кучей кешей. теперь обмен сообщениями - лучшее решение

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

сложная архитектура ЦПУ с кучей кешей. теперь обмен сообщениями - лучшее решение

один экземпляр std:vector на миллион строк с разными потоками сейчас нельзя использовать? В каждый надо отправлять персональную копию сообщением?

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

один экземпляр std:vector на миллион строк с разными потоками сейчас нельзя использовать? В каждый надо отправлять персональную копию сообщением?

Отличный способ - рекомендую попробовать.

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

Да я как сажусь домашку по с++ делать все время думаю про кеши и регистры. Не пропустила я чего? Сложная у меня архитектура ЦПУ или так, фигня для детей?

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

Мне препопаватель объяснил почему сигналы - это костыли

это бессПОРНО !
ждем преподавателя в треде, пусть нас повеселит, ТС уже не нужен

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

Там не будет рекурсии. Там только вызов QCoreApplication::processEvents. Внутри него будут обрабатываться слоты. А вот если архитектура через жопу, так это не Qt виноват.

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

Зачем 20, достаточно 2.

Как же достаточно. Это же разные сущности. :-) Или уже нет? Это называется уперлась за то чтобы «Хочу потоки и все тут…», а тут уже оказывается уже можно по очереди 20 устройств опросить. А перерисовать окно, а потом прочитать данные из порта в одном потоке - так нет, это обязательно нужен поток. Потоки нужно использовать к месту, когда реально упираешься в производительность одного потока, а не когда в голову стукнет.

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

Легко может случиться. Допустим, у тебя есть метод с долгими вычислениями, который вызывается как от сетевого события, так и от нажатия кнопки. Пришло сообщение из сети, запускаешь вычисления, они вызывают processEvents, а в этом время юзер удачно нажимает кнопку, запускается этот самый метод с вычислениями… Стектрейс будет выглядеть как-то так: event_loop>network_event>super_calculations>event_loop>button_click>super_calculations. Если метод с вычислениями нереентерабельный, то жди сюрпризов, хотя казалось бы нафига ему быть реентерабельным?

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

А перерисовать окно, а потом прочитать данные из порта в одном потоке

Это принципиальный дефект дизайна и незачет 100%.

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

Если ты хочешь потренироваться и шишки набить - то ладно. Если нужно проверенное отлаженное рабочее решение - то в Qt уже давно реализован обмен данными между потоками - сигналы/слоты. Нет, ну граждане, это капец какой-то.

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

Если ты хочешь потренироваться и шишки набить - то ладно. Если нужно проверенное отлаженное рабочее решение - то в Qt уже давно реализован обмен данными между потоками - сигналы/слоты. Нет, ну граждане, это капец какой-то.

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

И что делать, если он уже запущен? Вхолостую крутиться? Изначальный подход с вызовом processEvents ущербен, Qt Concurrent в помощь.

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

Это принципиальный дефект дизайна и не зачет 100%.

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

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

Ок, делай домашку, когда дойдёшь до такого момента как падение производительности при многопоточной обработке - свисти. Пока твои рассуждения на уровне «не читал, но осуждаю». Пробуй, попробуй заполнять вектор из другого потока напрямую, хуже не будет, почитай Таненбаума, задумайся почему в boost появился пакет signals/signals2

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

Это принципиальный дефект дизайна и не зачет 100%.

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

rumgot ★★★★★
()
Последнее исправление: rumgot (всего исправлений: 2)
Ответ на: комментарий от unC0Rr

Каждый инструмент должен использоваться к месту.

Работа с двумя потоками в qt (комментарий)

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

rumgot ★★★★★
()
Последнее исправление: rumgot (всего исправлений: 2)
Ответ на: комментарий от unC0Rr

Не, если тебе всё же действительно нужно проделать эти вычисления.

Тогда можно проверить, вызвана ли в данный момент нами функция processEvents.

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

Зачем мне доносить что это правильная архитектура еслия считаю ее неправильной и излишне переусложненной для этого простого случая?

Вот я бы к примеру сделала так:

std::vector<int> v;
std::atomic<bool> busy;

std::thread read_port([&v, &busy] {

тут опрашиваем и читаем датчики в v и пляшем как хотим

когда готово busy = false; и ждем когда его сбросят });

Это все!! Решение простое как 2 пальца.

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

Вынос тяжёлых вычислений из гуи-потока - это по делу даже при низкой средней загрузке цпу.

Тяжелых - ДА, бесспорно. Но случай чтения из последовательного порта - это тяжелый?

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

Зачем мне доносить что это правильная архитектура еслия считаю ее неправильной и излишне переусложненной для этого простого случая?

Qt - библиотека во многом используемая асинхронным способом. Действительно, использовать ее стандартный прием обмена данными (сигналы/слоты) и один поток - это переусложнение по сравнению с несколькими потоками и ручной самостоятельной реализацией обмена данными между потоками. :-)

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

Решение простое как 2 пальца.

меня терзают смутные сомненья ...

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

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

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

Когда ты учаcтвуешь в разработке решений уровня продакшен, то лучше когда используются знакомые всем стандартные проверенные решения, а не реализовывается уже существующий функционал. Для прикладника не нужно в каждом проекте с нуля реализовывать такие примитивы, ибо каждый написанный участок кода потребует время на проектирование/тестирование/отладку/исправление/поддержку - это все деньги компании.

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

По поводу boost - это песочнича, в которой обкатывается все иновационое, что может войти в std, например asio - это часть буста и очень активно используется различными приложениями. Signals - это и есть сигналы и слоты. Насчёт твоего решения - а потом мы организуем цикл проверки состояния и чем это отлино от eventloop qt

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

Ты точно все читаешь? GUI будет работать и чтение будет работать. Что значит «зависит». - Какой смысл ты в это вкладываешь? Ну перерисуется окно после чтения, и что?

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

знакомые всем стандартные проверенные решения

Вот чего ты такой упертый :). Еще теперь скажи, что std::thread нестандартный и непроверенный. Почему нас в основном обучают именно std? Может преподаватели не знают что Qt лучше?

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

Я делал проект, там Qt5.12.0, были чтение/запись из последовательного порта и Gui в одном потоке. В итоге программа работает на одноядерном селероне и за полтора года ни одного зависания или пропущенной посылки не было. А ты мне тут фантазируешь…

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

Ну перерисуется окно после чтения, и что?

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

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

Что я не понимаю в потоках

То что с ними тяжело работать...

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

Вот чего ты такой упертый

Я имею практической опыт применения.

Еще теперь скажи, что std::thread нестандартный и непроверенный.

Не переиначивай. Если есть Gui на Qt, то вручную реализовывать механизм обмена - это прихоть.

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

но ты не разрешаешь

Я не не разрешаю. Я за разумное использование (например очень затратная операция (опять таки с оговоркой про processEvents)).

А когда дело до чтения из порта дойдет?

Сработает сигнал на чтение, вызовется твой слот к этому сигналу - прочитаешь. ВСЕ. Какие проблемы.

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

Потому что вы нулевые, а препод скорее всего на 4 из 10. В продакшене сидят и работают на 7-8 из 10, по крайней мере на уровне тимлидов и некоторых мидлов, кто мидл только из-за того что тимлидов столько не требуется.

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

Ладно, я тупая и в продакшене не сижу. Тогда прошу указать недостатки моего решения выше (всего пять строчек) и опровергнуть мое утверждение, что работа с GUI в одном потоке с портом чревато при сложных вычислениях потерей данных.

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

Я вот тоже хочу тебя спросить, если нечего сказать, то зачем лезть в тему и надувать щеки «В продакшене сидят и работают на 7-8 из 10, ко-ко-ко».

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

прошу указать недостатки моего решения выше

Применительно к условиям задачи - не использование штатного класса qtserialport и его сигнал/слотов с попыткой преждевременной оптимизацией.


опровергнуть мое утверждение, что работа с GUI в одном потоке с портом чревато при сложных вычислениях потерей данных

Следует оценить скорость порта (очень низкая) и вычислительную мощность процессора (очень высокая) и не выдумывать серийных коней.

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

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

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.