Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

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

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

Купить рекламу на форуме - 42 тыс руб за месяц

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

Добрый день!

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

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

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

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

В поисковике форума в поле поиска введите многопоточность, выделите раздел Delphi, чекбокс Включая подразделы оставляем активным и жмите Начать поиск...
Вот одна из многих найденых тем по Вашему вопросу >>скачать несколько файлов одновременно (многопоточность не работает)
I am not a wizard, I am just learning.
Desc вне форума Ответить с цитированием
Старый 19.01.2020, 14: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, 14:22   #4
kotyara12
Пользователь
 
Регистрация: 28.04.2019
Сообщений: 12
По умолчанию

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

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

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

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

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

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

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

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

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

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

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

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


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


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