powered by simpleCommunicator - 2.0.36     © 2025 Programmizd 02
Форумы / Языки программирования семейства Pascal [закрыт для гостей] / Про многопоточность подскажите
30 сообщений из 30, показаны все 2 страниц
Про многопоточность подскажите
    #749002
Просто Трёп
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как-то писал многопоточное приложение, в общем и целом все получилось. Приложение было гуишным. Каждый поток создавался из своей TPanel и в нужные моменты слал ей SendMessage или PostMessage, этого хватало для полноценного обмена информацией и всяких оповещений. В результате мне даже понравилось.

А как быть в сервисе или консольном приложении, где окон нет? Вот надо мне оповестить основной поток о какой-нибудь промежуточной ерунде, произошедшей в отдельном потоке.
...
Рейтинг: 0 / 0
Про многопоточность подскажите
    #749006
IT-Клоп
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
надо тогда действовать через WinAPI

Скажем, применить механизм Event
...
Рейтинг: 0 / 0
Про многопоточность подскажите
    #749019
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Просто Трёп [игнорируется] 
Можно посылать сообщения потоку функцией PostThreadMessage. Тогда, если в потоке нет своего цикла обработки сообщений, его надо организовать при помощи например функции PeekMessage.

Насчёт евентов - это хороший вариант, но надо понимать, что поток, который будет ожидать срабатывания события при помощи функции WaitForSingleObject или WaitForMultipleObjects, будет в состоянии ожидания.

Службы никогда не писал (вроде, не припоминаю такого :) ) не особо представляю, что там удобно.
...
Рейтинг: 0 / 0
Про многопоточность подскажите
    #749021
Просто Трёп
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Угу.
...
Рейтинг: 0 / 0
Про многопоточность подскажите
    #749022
Просто Трёп
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
s62  01.04.2024, 15:26
[игнорируется]
Просто Трёп [игнорируется] 
Можно посылать сообщения потоку функцией PostThreadMessage. Тогда, если в потоке нет своего цикла обработки сообщений, его надо организовать при помощи например функции PeekMessage.

Насчёт евентов - это хороший вариант, но надо понимать, что поток, который будет ожидать срабатывания события при помощи функции WaitForSingleObject или WaitForMultipleObjects, будет в состоянии ожидания.

Службы никогда не писал (вроде, не припоминаю такого :) ) не особо представляю, что там удобно.
А обратно? Оно в обе стороны будет работать?
...
Рейтинг: 0 / 0
Про многопоточность подскажите
    #749089
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Просто Трёп  01.04.2024, 15:28
[игнорируется]
А обратно? Оно в обе стороны будет работать?
Если сообщения, то посылать можно из любого потока любому. Но чтобы поток мог принимать их, в нем должен быть цикл обработки сообщений. Вот в обычном Windows приложении на Delphi в главном потоке такой цикл уже есть, его VCL реализует.
Насчет событий, ну в моей практике отношения между потоками обычно были несимметричными. Например один поток подготавливает какие-то данные и выдает другому, чтобы тот передал их по сети. Или один поток всё время обменивается данными с каким-то устройством и периодически или сам их выдает или у него запрашивают какие-то данные.
Вот кстати со скуля один человек учебник написал несколько лет назад про многопоточность:
https://github.com/loginov-dmitry/multithread/blob/master/multithread_in_delphi_for_beginners.md

https://resql.ru/forum/topic.php?fid=58&tid=2036872
Правда не скажу сейчас, насколько хорошо написано, хотя начинал читать.
...
Изменено: 01.04.2024, 18:50 - s62
Рейтинг: 0 / 0
Про многопоточность подскажите
    #749091
IT-Клоп
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WaitForSingleObject можно ждать с таймаутом - опрашивая.

Ну в щем надо какую-то пилить костыльную синхронизацию полюбому...
...
Рейтинг: 0 / 0
Про многопоточность подскажите
    #749093
IT-Клоп
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в службе реализовывать обработку сообщений как в окне WinApi - не знаю, такая спорная имхо идея.
Окно - оно и живёт за счёт этого цикла.
А служба другим должна заниматься.
Ну и тем более такой тяжеловесный механизм использовать для общения между потоками - плохо имхо.
Из пушки по воробьям. у них же и так общая память.

Мессаги - это IPC для общения между окнами windows и между визуальными приложениями.

Потоки должны общаться через критически секции - вошел в неё , проверил, не пришло ли что-то, забрал, флаг снял, поехал далее.
Так будет наивысшая производительность достигнута.
...
Изменено: 01.04.2024, 18:55 - IT-Клоп
Рейтинг: 1 / 0
Нравится: Tosh
Про многопоточность подскажите
    #749094
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IT-Клоп  01.04.2024, 18:55
[игнорируется]
Ну и тем более такой тяжеловесный механизм использовать для общения между потоками - плохо имхо.
Да не особо тяжеловесный. Я сам правда один раз с этим дело имел, и то, другой человек делал, а я подрихтовывал. Сообщения через PostMessage, PostThreadMessage хороши тем, что асинхронная обработка - один поток не ждет, пока второй обработает сообщение. Добавил сообщение в очередь и дальше занимается своими делом. А с критическими секциями могут быть коллизии, когда один поток ждет другой. Но да, критические секции - норм, тоже ими не раз пользовался.
Неизвестно, что за служба у Просто Трепа и что за обмен данными там между потоками.

p.s. Один раз - сообщения от потока в другой доп. поток, так что там цикл обработки сообщений делали. А из доп. потока в основной поток GUI приложения передавать данные через PostMessage или оповещать через это, так это много раз использовал, это по-моему удобно. Ну со службами тут другая история.
...
Изменено: 01.04.2024, 19:05 - s62
Рейтинг: 0 / 0
Про многопоточность подскажите
    #749097
IT-Клоп
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
s62  01.04.2024, 19:00
[игнорируется]
IT-Клоп  01.04.2024, 18:55
[игнорируется]
Ну и тем более такой тяжеловесный механизм использовать для общения между потоками - плохо имхо.
Да не особо тяжеловесный. Я сам правда один раз с этим дело имел, и то, другой человек делал, а я подрихтовывал. Сообщения через PostMessage, PostThreadMessage хороши тем, что асинхронная обработка - один поток не ждет, пока второй обработает сообщение. Добавил сообщение в очередь и дальше занимается своими делом. А с критическими секциями могут быть коллизии, когда один поток ждет другой. Но да, критические секции - норм, тоже ими не раз пользовался.
Неизвестно, что за служба у Просто Трепа и что за обмен данными там между потоками.

p.s. Один раз - сообщения от потока в другой доп. поток, так что там цикл обработки сообщений делали. А из доп. потока в основной поток GUI приложения передавать данные через PostMessage или оповещать через это, так это много раз использовал, это по-моему удобно. Ну со службами тут другая история.
Но по сравнению с ним общая память потоков суперпроизводительна.
Это же как раз преимущество потоков.
Всего-то для них структуру в памяти организовать, таблицу, куда можно - добавить поток, добавить для него очередь сообщений.
и через эту очередь общаться, используя CriticalSection. Это именно для потоков - классика.
...
Изменено: 01.04.2024, 19:08 - IT-Клоп
Рейтинг: 0 / 0
Про многопоточность подскажите
    #749100
IT-Клоп
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для паттернодрочеров - это паттерн Observer, где поток может подписаться на сообщения себе.

Единственное - проверку надо в потоке костылить, это да. потому цикл придётся делать - для проверки очереди.

Надо смотреть, что за задача.
...
Рейтинг: 0 / 0
Про многопоточность подскажите
    #749101
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IT-Клоп  01.04.2024, 19:12
[игнорируется]
Надо смотреть, что за задача.
Вот-вот.
...
Рейтинг: 0 / 0
Про многопоточность подскажите
    #749103
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IT-Клоп [игнорируется] 
Один поток может подготавливать данные, потом "взводить" событие, а второй по событию их считывать и обрабатывать. Как одна из простых схем.
...
Изменено: 01.04.2024, 19:23 - s62
Рейтинг: 1 / 0
Нравится: IT-Клоп
Про многопоточность подскажите
    #749105
Просто Трёп
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да задача простая, отсюда забрал, туда запихал. Проблема только в том, что откуда берешь, может затыкаться по-своему, а куда пихаешь - по-своему. И на все это надо реагировать, буферизировать, если есть затык с пиханием.

И со скоростями непонятно. Что делать, если скорость пихания по каким-то причинам станет меньше скорости забирания. Это надо как-то отслеживать, играть размером буфера, если явление временное, звонить админу, если постоянное... А скорость забирания заранее неизвестна. Может, 100 UDP пакетов в минуту, а может, 1.

Щас оно в одном потоке работает, но если происходит затык, данные теряются, пока админ (или скрипт) сервис не перезапустит.
...
Рейтинг: 0 / 0
Про многопоточность подскажите
    #749106
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Просто Трёп [игнорируется] 
Если схема такая, что один пихает данные, а второй берет их и потом куда-то отправляет, то очередь можно использовать. Поток, который пихает, добавляет элементы в очередь. А который берет и что-то с ними делает, забирает из очереди по мере возможности, пока в очереди что-то есть.
Вот тут, если использовать не потокобезопасную очередь, можно как раз использовать критическую секцию. Первый поток входит в секцию, добавляет элемент, выходит, второй входит, забирает, выходит.
...
Изменено: 01.04.2024, 19:47 - s62
Рейтинг: 0 / 0
Про многопоточность подскажите
    #749108
Просто Трёп
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
s62  01.04.2024, 19:41
[игнорируется]
Просто Трёп [игнорируется] 
Если схема такая, что один пихает данные, а второй берет их и потом куда-то отправляет, то очередь можно использовать. Поток, который пихает, добавляет элементы в очередь. А который берет и что-то с ними делает, забирает из очереди по мере возможности, пока в очереди что-то есть.
Так оно сейчас так и работает, насколько я понял. Ивенты UDP компоненты в очередь сами становятся, если главный поток службы не успевает их обслужить.

О, надо будет зажурналировать потребление памяти службы и подождать, пока она заткнется. Посмотреть, увеличится жор памяти или нет.
...
Рейтинг: 0 / 0
Про многопоточность подскажите
    #749109
Просто Трёп
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В любом случае, нужен буфер на случай затыка отправки и возможность дампить этот буфер, если затык критический. А уж если делать хороший FIFO буфер, то и потоки надо делать.... Хороший буфер он сам по себе многопоточный.
...
Рейтинг: 0 / 0
Про многопоточность подскажите
    #749110
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Просто Трёп [игнорируется] 

Очереди-то есть:
https://docwiki.embarcadero.com/Libraries/Alexandria/en/System.Generics.Collections.TQueue
https://docwiki.embarcadero.com/Libraries/Alexandria/en/System.Generics.Collections.TThreadedQueue
Я когда-то сам на основе динамического массива очередь делал. Но тут уже готовые. )
...
Рейтинг: 1 / 0
Нравится: Просто Трёп
Про многопоточность подскажите
    #749112
Просто Трёп
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну что я могу сказать... Дельфи жив!
...
Рейтинг: 1 / 0
Нравится: s62
Про многопоточность подскажите
    #1214152
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В программе есть долгий расчет, точнее - подбираются оптимальные параметры, длительность зависит от количества параметров. Максимальное - 4, считается долго, секунд 50 на одном тесте было. Три параметра - несколько секунд, 1-2 почти мгновенно. Более актуально 1-2-3. Но долгое время не так уж страшно, т.к. операция делается нечасто, находятся коэффициенты для калибровки, которой потом пользуются какое-то время, м.б. месяцы и т.п.

Посмотрел, естественно, загружается один процессор, подумал насчет распараллеливания. В Delphi есть параллельное for. Но, увы, так прямо просто сходу не получилось. В расчетах используется одна большая структура данных, в ней меняются несколько параметров (те, которые подбираются) и делается расчет калибровки, а потом коэффициента детерминации для набора точек (проб), т.е. насколько хорошо кривая описывает положения этих точек. Естественно, если тупо распараллелить, то разные потоки будут независимо менять эту структуру и получится ерунда. Пока отложил на более низкую степень приоритета, подумать так сказать в фоновом режиме, как это сделать.

Попутно выяснил, читая обсуждения на стековерфлоу что не всё благополучно с этим TParallel.For в Delphi. Есть баг в последней версии, который можно попатчить самому или обойти некоторыми действиями. Судя по обсуждениям на стековерфлоу, не всё там и реализовано очень хорошо.
Но так, для инфы, есть в Delphi сейчас TTask, IFuture, TParallel.For и другие штуки, цель которых облегчить написание многопоточного или асинхронного кода.
...
Рейтинг: 0 / 0
Про многопоточность подскажите
    #1214647
Просто Трёп
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TTask - это фоновое задание? Как в 1С?
...
Рейтинг: 0 / 0
Про многопоточность подскажите
    #1214797
Гарыныч
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[игнорирует гостей кроме]
[spoiler][size=4][b]Клоп и Сталкер, жидки вы обоссаные, просто пройдите нахуй![/b][/size] [:nahui][/spoiler]
Просто Трёп  27.11.2024, 13:20
[игнорируется]
TTask - это фоновое задание? Как в 1С?
http://www.proghouse.ru/programming/36-delphi-xe7-ppl
Цитата 
[игнорируется]
....
Использование TTask
TTask – это класс, который позволяет запускать одну задачу или несколько задач параллельно. При этом вам не придётся создавать поток и управлять им. Класс TTask реализует интерфейс ITask. В интерфейсе ITask в вашем распоряжении есть функции для запуска (Start), ожидания (Wait) и отмены (Cancel) задачи и статус (Status), позволяющий узнать, что происходит с задачей. Вот возможные статусы задачи: Created (задача создана), WaitingToRun (задача ожидает окончания выполнения другого процесса), Running (задача выполняется), Completed (задача завершена), WaitingForChildren (задача ожидает окончания выполнения дочерней задачи), Canceled (задача была отменена), Exception (при выполнении задачи произошла ошибка).
...
Гарыныч :
Клоп-жидок, тебе в 1991 году сколько годиков было? 19?
Рейтинг: 0 / 0
Про многопоточность подскажите
    #1214817
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Просто Трёп  27.11.2024, 13:20
[игнорируется]
TTask - это фоновое задание? Как в 1С?
TTask - Это класс, который позволяет выполнить передаваемую процедуру в фоновом потоке.
...
Изменено: 27.11.2024, 13:51 - s62
Рейтинг: 0 / 0
Про многопоточность подскажите
    #1221952
Просто Трёп
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
s62  27.11.2024, 13:51
[игнорируется]
Просто Трёп  27.11.2024, 13:20
[игнорируется]
TTask - это фоновое задание? Как в 1С?
TTask - Это класс, который позволяет выполнить передаваемую процедуру в фоновом потоке.
Просто в другом потоке? А синхронизации данных вообще никакой? Ну, я выдал ей какие-то данные, запустил и жду, пока она их обработает. К данным не обращаюсь, пока она не закончит. Так?
...
Рейтинг: 0 / 0
Про многопоточность подскажите
    #1221962
Просто Трёп
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гарыныч  27.11.2024, 13:48
[игнорируется]
Цитата 
[игнорируется]
WaitingToRun (задача ожидает окончания выполнения другого процесса)
Какого такого процесса?
...
Рейтинг: 0 / 0
Про многопоточность подскажите
    #1222042
Гарыныч
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[игнорирует гостей кроме]
[spoiler][size=4][b]Клоп и Сталкер, жидки вы обоссаные, просто пройдите нахуй![/b][/size] [:nahui][/spoiler]
Гарыныч  27.11.2024, 13:48
[игнорируется]
Цитата 
[игнорируется]
WaitingToRun (задача ожидает окончания выполнения другого процесса)
Просто Трёп  28.11.2024, 17:14
[игнорируется]
Гарыныч  27.11.2024, 13:48
[игнорируется]
Цитата 
[игнорируется]
WaitingToRun (задача ожидает окончания выполнения другого процесса)
Какого такого процесса?
другого

http://www.proghouse.ru/programming/36-delphi-xe7-ppl
Цитата 
[игнорируется]
А теперь попробуем выполнить несколько задач параллельно. Для этого нужно создать массив задач, запустить задачи и ждать когда они выполнятся. Для ожидания есть две статические функции класса TTask: WaitForAll (ожидать выполнения всех задач) и WaitForAny (ожидать выполнения хотя бы одной из задач).

uses System.Threading, System.SyncObjs;

procedure TForm1.Button2Click(Sender: TObject);
var
tasks: array of ITask;
task: ITask;
value: integer;

procedure CreateTasks;
begin
value := 0;
tasks := [
TTask.Create(procedure()
begin
//Выполняем задачу 5 секунд.
Sleep(5000);
//Добавляем к результату 5000.
TInterlocked.Add(value, 5000);
end
),
TTask.Create(procedure()
begin
//Выполняем задачу 3 секунды.
Sleep(3000);
//Добавляем к результату 3000.
TInterlocked.Add(value, 3000);
end
)
];
end;

begin
//Создаём задачи и инициализируем переменную value.
CreateTasks;
//Запускаем все задачи в массиве.
for task in tasks do
task.Start;
//Ждём выполнение всех задач.
TTask.WaitForAll(tasks);
//Результат будет 8000.
ShowMessage('Все задания выполнены. Результат: ' + IntToStr(value));
//Создаём задачи и инициализируем переменную value.
CreateTasks;
//Запускаем все задачи в массиве.
for task in tasks do
task.Start;
//Ждём выполнение любой из задач.
TTask.WaitForAny(tasks);
//Результат будет 3000.
ShowMessage('Все задания выполнены. Результат: ' + IntToStr(value));
end;
И напоследок, ещё один пример, в котором я покажу, как обращаться к свойствам и контролам формы из процедуры задачи, как проверять статус задачи и как отменить её выполнение.
...
Гарыныч :
Клоп-жидок, тебе в 1991 году сколько годиков было? 19?
Изменено: 28.11.2024, 17:27 - Гарыныч
Рейтинг: 0 / 0
Про многопоточность подскажите
    #1223372
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Просто Трёп  28.11.2024, 17:13
[игнорируется]
s62  27.11.2024, 13:51
[игнорируется]
Просто Трёп  27.11.2024, 13:20
[игнорируется]
TTask - это фоновое задание? Как в 1С?
TTask - Это класс, который позволяет выполнить передаваемую процедуру в фоновом потоке.
Просто в другом потоке? А синхронизации данных вообще никакой? Ну, я выдал ей какие-то данные, запустил и жду, пока она их обработает. К данным не обращаюсь, пока она не закончит. Так?
Читай доки! )
...
Рейтинг: 0 / 0
Про многопоточность подскажите
    #1225977
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Из старой книжки (Тексейра и Пачеко, Делфи 5 руководство разработчика).
CritSecMutexes.png
...
Изменено: 29.11.2024, 14:32 - s62
Рейтинг: 0 / 0
Про многопоточность подскажите
    #1228557
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
s62  28.11.2024, 23:10
[игнорируется]
Просто Трёп  28.11.2024, 17:13
[игнорируется]
s62  27.11.2024, 13:51
[игнорируется]
Просто Трёп  27.11.2024, 13:20
[игнорируется]
TTask - это фоновое задание? Как в 1С?
TTask - Это класс, который позволяет выполнить передаваемую процедуру в фоновом потоке.
Просто в другом потоке? А синхронизации данных вообще никакой? Ну, я выдал ей какие-то данные, запустил и жду, пока она их обработает. К данным не обращаюсь, пока она не закончит. Так?
Читай доки! )
С одной стороны документацию читать вообще полезно. ) С другой - я сам про эти классы и интерфейсы знаю в основном из документации, по-моему ни разу не пользовался. Как-то больше по-старинке через класс TThread делал. Хотя в принципе понятно, где бы можно было применить TTask. Вот например в одной из программ, которой сейчас занимаюсь, есть потоки которые живут в принципе всё время, пока работает программа - дополнительные рабочие потоки, в которых идет обмен по сети с устройствами измерительной установки. С одной установкой - один рабочий поток, плюс дополнительные могут стартовать. Программа может работать с несколькими установками, соответственно несколько таких рабочих потоков.
А например запись в лог делается из доп. потока, которому передается строка, имя файла лога (или может писаться в лог по-умолчанию), поток создается, открывает файл, дописывает в конце строку, закрывает файл и прекращает свою работу и уничтожается. Делается через критическую секцию, на случай коллизий. Вот тут наверное можно было бы сделать через TTask. Описать процедуру и запустить её через TTask.
Кстати, один момент тут - TTask использует пул потоков.
Насчёт получения результата есть интерфейс IFuture, тоже по докам и примеру в доках знакОм. Там можно вызвать, позднее попытаться получить результат, и если он уже есть, то сразу получаем, если нет, то вызывающий поток ждет, пока будет. Есть ещё свойство Status, можно посмотреть, завершился таск или нет или в каком сейчас состоянии.
...
Изменено: 29.11.2024, 21:41 - s62
Рейтинг: 0 / 0
Про многопоточность подскажите
    #1228632
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
s62  29.11.2024, 21:39
[игнорируется]
Там можно вызвать
Неточно написал, имел в виду запустить задачу, вызвать метод Start.
...
Рейтинг: 0 / 0
30 сообщений из 30, показаны все 2 страниц
Форумы / Языки программирования семейства Pascal [закрыт для гостей] / Про многопоточность подскажите
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]