|
|
Регистрация Восстановить пароль |
Повторная активизация e-mail |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
|
Опции темы | Поиск в этой теме |
24.08.2016, 16:39 | #1 |
Форумчанин
Регистрация: 09.09.2008
Сообщений: 418
|
Синхронизация потоков
Подскажите, пожалуйста, на моем примере как правильно синхронизировать несколько потоков.
На форме есть n количество combobox, каждый заполняется из разных таблиц БД. Я делал так 1. Выключаю первый combobox. ( synchronize(comboboxN.enable = false) ) 2. В Execute создаю TstringList и заполняю его данными из таблицы N, т.е. while not tableN.eof do TstringListN.add(tableN.poleN) 3. Потом synchronize (comboboxN.items := TstringListN) 4. И включаю ComboboxN ( synchronize(comboboxN.enable = false) ) Так я проделываю со всеми Combobox по очереди, а хочется запустить несколько потоков, заполнить все Combobox и по окончании включить сразу все. Т.е. я понимаю так, что должен быть поток, который бы запускал все остальные и проверял : все законченно или нет. Если все потоки отработали, то включил все combobox’ы. Подскажите как это осуществить? |
24.08.2016, 16:52 | #2 |
Старожил
Регистрация: 17.11.2010
Сообщений: 18,922
|
Смысл этого в чем?
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
|
24.08.2016, 17:01 | #3 |
Форумчанин
Регистрация: 09.09.2008
Сообщений: 418
|
|
24.08.2016, 17:46 | #4 |
Старожил
Регистрация: 26.04.2008
Сообщений: 2,645
|
Один из примеров для WaitFor***Objects (без обработки ошибок и зависаний потоков, а также без чистки за собой мусора)
Код:
https://msdn.microsoft.com/ru-ru/lib...(v=vs.85).aspx Также полезно ознакомится с семафорами |
24.08.2016, 17:48 | #5 |
Форумчанин
Регистрация: 09.09.2008
Сообщений: 418
|
Спасибо, теперь есть более четкое направление для самообразования
Последний раз редактировалось tarakan1983; 24.08.2016 в 17:53. |
24.08.2016, 20:08 | #6 | ||
Лис
Старожил
Регистрация: 18.09.2015
Сообщений: 2,409
|
tarakan1983
Вы выбрали очень плохую задачу для обучения. 1) Быстрее не будет. Если раньше галочки загорались постепенно. То теперь программа будет висеть дольше и всё будет загораться одновременно. 2) Не все БД поддерживают парольную работу. А те которые поддерживают возвращают разные версии таблиц. Цитата:
Цитата:
http://docwiki.embarcadero.com/RADSt...amming_Library Создаёшь анонимную функцию и вызываешь в параллельном цикле. После параллельного цикла делаешь обычный цикл и включаешь все галочки. Пример выше это очень мощное средство сокращает код в 1000 раз. Паралельный цикл сам создает и уничтожает потоки. И плюс будет проверяет завершились они или нет. Т.е. на каждую итерацию создаёт по потоку и итерации будут вызываться параллельно*. А основной поток он всегда есть, его создавать не надо. *параллельно- реально или псевдопаралельно.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал . Последний раз редактировалось Pavia; 24.08.2016 в 20:15. |
||
24.08.2016, 21:03 | #7 | |
Форумчанин
Регистрация: 09.09.2008
Сообщений: 418
|
Цитата:
Если не затруднит можете построчный анализ ЭТОГО написать и объяснить на палочках (красненьких, зелененьких... как в первом классе ) |
|
25.08.2016, 00:38 | #8 | |
Лис
Старожил
Регистрация: 18.09.2015
Сообщений: 2,409
|
Цитата:
Самое трудное это сделать первые шаги. Вам не нужно знать почему так, а не иначе. Вы должны воспринимать свойства и методы как аксиомы геометрии или законы механики. Второй шаг тоже важен. Ваш мозг будет цепляться за соломинки искать аналогии, метафоры или напротив на основе частных предположений строить общие свойства. Тут надо перебороть себя и перестать упрощать. Для этого надо в точности зачитывать описания свойства объектов. До тех пор пока свойства не отпечатаются у вас в мозгу и не будут отскакивать от зубов. Запоминаем анонимная функция: - не имеет имени; - объявляется и описывается в коде как арифметическое выражение, а не в секции деклорации(interface) или реализации(implementation). - является объектом! Т.е. её можно передать как параметр в функцию. А также присваивать методу класса. Синим цветом я выделил анонимную процедуру, также можно объявить анонимную функцию. Код:
Статические методы класса. Статические методы класса можно вызывать не создавая объект. Код:
Метод аналогичен коду ниже Код:
Синхронизация бывает 3-х родов. На самом деле это одно и тоже. Просто разные термины пришедшие при взгляде на проблему с разных точек. 1) По-данным: 1.1) Атомарные операции, которые выполняются не разрывно. 1.2) Мьютекс 2) По-коду: 2.1) Критическая секция. 2.2) Светофорах. 3) По-времени: 3.1) Разнесённые обращения во времени. Карусель (RoundRobin). 3.2) На событиях. К примеру WaitAll или WaitAny Этот список далеко не полный: есть спин-локи, защищенные очереди, сообщения и тд. Как обезопасить переменные? Локальные переменные и параметры функций в защите не нуждаются так как располагаются в разных участках памяти. Поэтому обращения к ним не пересекается. Общие переменные для потоков должны быть защищены. А также ввод и вывод он тоже должен быть безопасным. VCL не безопасен программист должен сам позаботиться об этом. TInterlocked применяется для синхронизации по-данным. Код:
изменяем на TInterlocked.Increment получаем правильную сумму 101 TParallel.For использует пул-потоков для автоматического создания и уничтожения потоков. Много потоков плохо сказывается на производительности. Мало тоже. Вот пул-потоков время от времени определяет производительности и создает или уничтожает потоки. Каждая итерация цикла выполняется параллельно во-времени. В переменную I передаётся номер цикла. Далее хотелось бы рассказать про шаблоны-программ работающих параллельно. А вот вопросы оптимизации связанные напрямую с устройством объекты синхронизации оставить на потом. Я выделяю следующие шаблоны: 1) Толкучка. 2) Карусель. 3) Бос-рабочие 4) Рабочий-диспетчер
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал . Последний раз редактировалось Pavia; 25.08.2016 в 10:00. |
|
25.08.2016, 09:59 | #9 |
Лис
Старожил
Регистрация: 18.09.2015
Сообщений: 2,409
|
Как получить результат и как синхронность выполнения при вызове TParallel.For ?
За синхронность отвечает компилятор вернее библиотека System.Threading. Тут о чём либо думать не стоит. А вот чтобы получить результаты, предлагаю ознакомиться с примером. Код:
Тут используется так называемая барьерная синхронизация. Все ездили на машинах и видели как работает шлагбаум? Представте себе закрытый шлагбаум на переезде в четырёхполосной дороге. Он и есть такой барьер. На разных полосах машины подъезжают к шлагбауму в разное время. А после когда барьер открывается все стартуют одновременно. Так и тут время работы разных потоков разное. Но синхронизируются они в конце параллельного-цикла. Цикал ждёт пока самый медленный поток не закончит работать. Как только закончит барьерная блокировка снимается. И начинает работать основной поток. В нём обычным последовательным циклом мы собираем результаты. Код:
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал . |
25.08.2016, 13:58 | #10 | |
Форумчанин
Регистрация: 09.09.2008
Сообщений: 418
|
Цитата:
|
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Синхронизация потоков | _ZixeL_ | Общие вопросы Delphi | 14 | 10.09.2015 22:23 |
Синхронизация потоков | _Bers | Общие вопросы C/C++ | 5 | 23.12.2011 22:57 |
Синхронизация потоков | добрый_фей | Помощь студентам | 5 | 09.12.2011 19:57 |
Синхронизация потоков | kardinal94 | Общие вопросы Delphi | 5 | 29.11.2010 21:13 |