Синхронизация потоков

test1c

Member
Joined
Jul 25, 2010
Messages
20
Reaction score
5
Я попробую предложить самый простой вариант.
В модуле формы локальную переменную-счетчик. при старте ставим его в 0.
В "Синхронайз" каждого потока увеличивать этот счетчик и проверять, если он равен количеству комбобоксов сделать все комбо доступными.
 

yyjksw

Member
Joined
Jul 17, 2008
Messages
20
Reaction score
6
The fastest synchronization for an executable is the TCriticalSection of SyncObj.

Guaranteed to be faster than semaphores or mutexes.

We recommend that you look at several ways to synchronize.
 

dimonak90

New member
Joined
Jul 14, 2009
Messages
4
Reaction score
1
Age
57
Location
Hungary
В основном потоке нужно задизэйблить все элементы UI, создать поток обновления для каждого элемента UI, каждый поток должен по окончанию послать событие на enable. Но комментатор N11 всё равно прав. Выиграш будет нулевой, в большинстве случаев станет только хуже.
 

vegebi

Member
Joined
Mar 22, 2017
Messages
5
Reaction score
2
Я попробую предложить самый простой вариант.
В модуле формы локальную переменную-счетчик. при старте ставим его в 0.
В "Синхронайз" каждого потока увеличивать этот счетчик и проверять, если он равен количеству комбобоксов сделать все комбо доступными.

При использовании такого способа следует указать атрибут Volatile для счётчика и можно будет обойтись без Synchronize для работы с ним:
http://docwiki.embarcadero.com/RADStudio/Berlin/en/Compiler_Attributes#Volatile

В свежих версиях Delphi появились библиотека Parallel Programming Library, которая упрощает запуск нескольких заданий в отдельных потоках и их синхронизацию с основным потоком:
http://docwiki.embarcadero.com/RADStudio/Seattle/en/Using_the_Parallel_Programming_Library
http://docwiki.embarcadero.com/RADS...g_TTask_from_the_Parallel_Programming_Library
 

X-Cite!

Member
Joined
Mar 24, 2014
Messages
25
Reaction score
5
Location
Минск
Подскажите, пожалуйста, на моем примере как правильно синхронизировать несколько потоков.
На форме есть 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’ы. Подскажите как это осуществить?

Примерно тоже самое.
В нескольких потоках заполняете tstringlist и через synchronize назначаете каждому свой через assign
vcl - Однопоточная и работать с компонентами параллельно нельзя.
 

d_z

New member
Joined
Jan 21, 2005
Messages
4
Reaction score
0
С VCL вообще не стоит работать из других потоков даже со всякими там критическими секциями, семафорами, эвентами и т.д., т.к. у VCL обработка очереди сообщений идёт в своём (главном) потоке и никак с вашими самоделками не синхронизируется. При такой работе можно словить странное поведение контролов.
Если уж получать данные в несколько потоков, то стоит передавать в поток для чего и какие данные он получает и затем через Synchronize возвращать результат. Как вариант можно класть результат в очередь и сигналить форме через PostMessage.
С OmniThreadLirary и новыми классами для многопоточной работы из новых дельфей не работал, но можно там посмотреть что-то готовое на эту тему (Task-и там всякие, готовые пулы потоков и т.д.).
 

falsenull

New member
Joined
May 2, 2017
Messages
1
Reaction score
0
Какая версия Delphi?
Если не очень старая, стоит посмотреть в сторону TTask - там легко управлять пулом потоков
 

kefeka

New member
Joined
Mar 28, 2016
Messages
4
Reaction score
0
Подскажите, пожалуйста, на моем примере как правильно синхронизировать несколько потоков.
На форме есть 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’ы. Подскажите как это осуществить?

Для кто нашел ветку, но не решил проблему)
Если хочешь поток, то создай компонент на основе adotable где во время выполнения потока на while ставишь sleep пока не выполнится, т.е не изменится dataset твой.

Идея реализации заполнения combobox через stringlist очень плоха на мой взгляд.
Использовать стоит lookupcombobox, тех же devexpress.
 
Top