Форум программистов
 
О проблемах, например, с регистрацией пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail, а тут можно восстановить пароль.

Вернуться   Форум программистов > Delphi > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail


Ответ
 
Опции темы
Старый 18.01.2020, 22:37   #1
kotyara12
Пользователь
 
Регистрация: 28.04.2019
Сообщений: 12
Вопрос Очередь сообщений для обмена данными между потоками

Добрый день!

Есть необходимость организовать обмен данными между несколькими потоками. Суть задачи в следующем: множество разных потоков-отправителей отправляют сообщения одному выбранному потоку-приемнику. Приемник должен по очереди их все обрабатывать. Все потоки не имеют окон и не взаимодействуют с главным окном. Нужен совет - как правильно это организовать?

В сети полно примеров, это да. Все разные. Каша в голове. Например:
1. Нашел примеры через PostThreadMessage, но там вроде бы как требуется HWND (не уверен), потому что PostThreadMessage нельзя отправить потоку, не имеющему окна (врут???). И как быть с очередью (несколько разных потоков могут практически одновременно отправить сообщения приемнику)?
2. Есть примеры с Event, но пока мне непонятно, как сделать очередь.

Весь вечер читаю, но пока не смог определиться, как проще и правильнее реализовать задачу. Нужен просто совет, в каком направлении двигаться.

Заранее спасибо.
kotyara12 вне форума Ответить с цитированием
Старый 19.01.2020, 05:12   #2
Desc
Форумчанин
 
Аватар для Desc
 
Регистрация: 21.11.2007
Сообщений: 588
По умолчанию

В поисковике форума в поле поиска введите многопоточность, выделите раздел Delphi, чекбокс Включая подразделы оставляем активным и жмите Начать поиск...
Вот одна из многих найденых тем по Вашему вопросу >>скачать несколько файлов одновременно (многопоточность не работает)
Desc вне форума Ответить с цитированием
Старый 19.01.2020, 15:07   #3
kotyara12
Пользователь
 
Регистрация: 28.04.2019
Сообщений: 12
По умолчанию

В FreeRTOS на микроконтроллерах есть такая готовая штука - очередь (http://microsin.net/programming/arm/freertos-part2.html)
xQueueCreate / xQueueSendToFront / xQueueSendToBack / xQueueReceive / xQueuePeek
Все уже готовое, оптимизированное под многопоточность, ничего изобретать не надо.
Вот нужно точно то же самое, но сделать на Delphi
kotyara12 вне форума Ответить с цитированием
Старый 19.01.2020, 15:22   #4
kotyara12
Пользователь
 
Регистрация: 28.04.2019
Сообщений: 12
По умолчанию

Цитата:
Вот одна из многих найденых тем по Вашему вопросу >>скачать несколько файлов одновременно (многопоточность не работает)
А где здесь очереди??? Вообще не применимо к моей задаче.

Про то, что информации на форуме много, я прекрасно знаю. Причем предлагают десятки разных варантов реализации для разных целей. Все их пробовать и проверять - убить впустую недели времени. Я вечера в поисках весь день провел, а толку ноль. Мне нужно НАПРАВЛЕНИЕ, куда двигаться, какую технологию использовать, а дальше "Гугл до Киева доведет".
kotyara12 вне форума Ответить с цитированием
Старый 19.01.2020, 15:25   #5
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,088
По умолчанию

kotyara12 таки в чём вопрос? Берете массив делаете 4 функции:
1. Поместить данные в очередь.
2. Проверить данные в очереди.
3. прочитать данные из очереди.
4. И поместить данные в очереди и дождаться ответа.
Очередь делаете приватной и защищаете доступ при помощи мьютекса.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .

Последний раз редактировалось Pavia; 19.01.2020 в 15:29.
Pavia на форуме Ответить с цитированием
Старый 19.01.2020, 15:47   #6
kotyara12
Пользователь
 
Регистрация: 28.04.2019
Сообщений: 12
По умолчанию

Цитата:
Сообщение от Pavia Посмотреть сообщение
kotyara12 таки в чём вопрос? Берете массив делаете 4 функции:
1. Поместить данные в очередь.
2. Проверить данные в очереди.
3. прочитать данные из очереди.
4. И поместить данные в очереди и дождаться ответа.
Очередь делаете приватной и защищаете доступ при помощи мьютекса.
Таки да. Я так и делал. Только защищал критической секцией, не суть. Проблема в том, что потоков много, очередей между ними тоже много. Иногда происходит взаимная блокировка потоков. Хочется "красивого" решения, как это сделано в FreeRTOS - просто, прозрачно, аккуратно. Но походу, в WinAPI такого нет.
kotyara12 вне форума Ответить с цитированием
Старый 19.01.2020, 15:51   #7
kotyara12
Пользователь
 
Регистрация: 28.04.2019
Сообщений: 12
По умолчанию

Цитата:
Сообщение от Pavia Посмотреть сообщение
kotyara12 таки в чём вопрос? Берете массив делаете 4 функции:
1. Поместить данные в очередь.
2. Проверить данные в очереди.
3. прочитать данные из очереди.
4. И поместить данные в очереди и дождаться ответа.
Очередь делаете приватной и защищаете доступ при помощи мьютекса.
Спасибо! Пока писал предыдущий ответ, понял как нужно сделать. Еще раз спасибо, что натолкнули на идею.
kotyara12 вне форума Ответить с цитированием
Старый 19.01.2020, 17:24   #8
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,088
По умолчанию

FreeRTOS потоки получают доступ по кругу. В виндоусе на основе приоритетов. Когда задачи работают по кругу их проще синхронизировать. Я бы предпочел использовать таймер для опроса других потоков. Но это не ваш случай так как у вас поток общается каждый с каждым.
Зачем Вы так усложнили систему честно непонятно. Обычно берут СУБД и там уже транзакциями разливают общий доступ.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia на форуме Ответить с цитированием
Старый 19.01.2020, 20:22   #9
kotyara12
Пользователь
 
Регистрация: 28.04.2019
Сообщений: 12
По умолчанию

Цитата:
Сообщение от Pavia Посмотреть сообщение
FreeRTOS потоки получают доступ по кругу. В виндоусе на основе приоритетов. Когда задачи работают по кругу их проще синхронизировать. Я бы предпочел использовать таймер для опроса других потоков. Но это не ваш случай так как у вас поток общается каждый с каждым.
Зачем Вы так усложнили систему честно непонятно. Обычно берут СУБД и там уже транзакциями разливают общий доступ.
Не каждый с каждым. Передача данных всегда однонаправленная (отправитель -> получатель), но отправителей может быть много.

Например: поток watchDog. Каждый "рабочий" поток периодически отчитывается одному потоку-"ревизору", дабы отследить зависшие потоки и перезапустить. Вот тут я хотел применить очередь, но сейчас сделал по другому.

А что из всего этого выходит можно посмотреть в telegram - @fl_monitor_bot. Сейчас переписываю все с нуля...

Последний раз редактировалось kotyara12; 19.01.2020 в 20:30.
kotyara12 вне форума Ответить с цитированием
Старый 20.01.2020, 23:04   #10
kotyara12
Пользователь
 
Регистрация: 28.04.2019
Сообщений: 12
По умолчанию

Информация для тех, кто будет искать что-то подобное и наткнется на этот пост.
Велосипед изобретать не нужно: потокобезопасная очередь есть в Delphi (начиная с XE2, насколько я понял) и называется она TThreadedQueue. Все остальное можно узнать в справке и интернете.
kotyara12 вне форума Ответить с цитированием
Ответ

Здесь нужно купить рекламу за 20 тыс руб в месяц! ) пишите сюда - alarforum@yandex.ru
Без учёта ботов - 20000 человек в день, 350000 в месяц.

Опции темы


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Есть ли простой способ мгновенного обмена событиями и данными между локальными html, js ? Illusiony JavaScript, Ajax 8 01.06.2019 09:42
Скрипт обмена данными WorldMaster Microsoft Office Word 0 17.06.2018 19:31
Обмен данными между двумя потоками. MrFakir C# (си шарп) 14 02.12.2013 22:03
ускрпение обмена данными sasha2121 Железо 0 25.01.2011 15:58


Проекты отопления, пеллетные котлы, бойлеры, радиаторы
интернет магазин respective.ru
Пеллетный котёл Emtas
котлы EMTAS