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

tarakan19832

Турист
Регистрация
12 Авг 2016
Сообщения
6
Реакции
0
Credits
6
Подскажите, пожалуйста, на моем примере как правильно синхронизировать несколько потоков.
На форме есть 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’ы. Подскажите как это осуществить?
 

isam_os

Турист
Регистрация
28 Авг 2016
Сообщения
3
Реакции
0
Credits
6
попробуй создать на каждый комбо , отдельный поток ? или у тебя там их мильён ?
 

LeshaRB

Свой
Регистрация
11 Июн 2007
Сообщения
319
Реакции
467
Credits
25
Как выполнить N операций M потоками, как-то так я бы гуглил
 

dustypup

Турист
Регистрация
27 Ноя 2008
Сообщения
21
Реакции
1
Credits
57
Создай несколько экземпляров потока.
Передай в каждый поток указатель на свой комбобокс.
В потоке заполняй комбобокс и enable его.
Запускай все потоки одновременно.
 

fets

Турист
Регистрация
4 Окт 2011
Сообщения
7
Реакции
1
Credits
14
synchronize используется для GUI, для синхронизации действий, лучше использовать симофоры, пока действие не будет сделано семафор дальше не пустит:

SemaphoreTask : THandle;
.....
SemaphoreTask := CreateSemaphore(nil, 0, 2147483647, '');
.....

// Эта команда WaitForSingleObjectEx будет ожидать с любого участка программы --> ReleaseSemaphore(SemaphoreTask, 1, nil);
WaitForSingleObjectEx(SemaphoreTask , INFINITE, True);
....
// закрыть семафор
CloseHandle(SemaphoreTask );

Таким образом можешь синхронизировать любый задачи!
 

Earl_Vadim

Турист
Регистрация
1 Авг 2015
Сообщения
7
Реакции
1
Credits
24
Есть такое простое слово как mutex - оно все объясняет.
 

tarakan1983

Турист
Регистрация
30 Июл 2016
Сообщения
8
Реакции
0
Credits
16
Есть такое простое слово как mutex - оно все объясняет.

Я понимаю, Вы профессионал и это слово Вам все объяснят, но мне не очень. Не могли бы Вы вкратце с примерчиком? Или дайте ссылку на пример.
 

Earl_Vadim

Турист
Регистрация
1 Авг 2015
Сообщения
7
Реакции
1
Credits
24
Нет. я не профессионал.. все сам ищу через поиск.
Суть mutex - тотже симафор... просто поиском вы больше инфы найдете по слову mutex, чем по слову Semaphore ..

а вообще более полного и более правильного описания потоков чем это

Скрытое содержимое доступно для зарегистрированных пользователей!


вы не найдете.
 

alchemist131

Турист
Регистрация
16 Ноя 2010
Сообщения
10
Реакции
0
Credits
21
По вопросам синхронизации фундаментальный труд - Джеффри РИХТЕР "Создание эффективных WIN32-приложений с учётом специфики 64-разрядной версии Windows". В нем описаны все основные элементы WinAPI и особенности их использования (семафоры, мьютексы в том числе). Переложить на Delphi труда не составит.
В описанной задаче в потоке-синхронизаторе, на мой взгляд, необходимости нет. Каждый поток может независимо от другого заполнять TStringList из базы. Дальнейший перенос в TComboBox осуществляется с помощью Synchronize. Этот метод сам по себе не даст другим потокам обратиться к основному потоку Vcl, пока какой-либо пишет данные в TComboBox.
 

Keoda

Местный
Регистрация
19 Ноя 2014
Сообщения
31
Реакции
25
Credits
62
Если у тебя доступ к базе данных на чтение открыт свободно, я бы сделал потоки для каждого комбобокса:
hThr = CreateThread(NULL, 0, ThreadProcName, pCombobox, 0, &dwThrID);
В потоке читал бы базу и обновлял содержимое формы.
Если хочешь включить сразу все комбобоксы пусть каждый поток выставит Event по окончании работы, а основной поток пусть ждёт все эти Events через WaitforMultipleObjects. только я настоятельно рекомендую не писать INFINITE, чтобы не вешать поток, лучше взять заведомо большее время, за которое точно должны сработать потоки (60000 мс например).
DWORD rez = WaitforMultipleObjects(iCheckBoxNumber, evThreadHadDoneItsWork, TRUE, 60000);
if(rez == WAIT_TIMEOUT)
{
// Ждали минуту потоки не завершились
}
else if (rez == WAIT_OBJECT_0) {включить все комбы}
 
Последнее редактирование модератором:

robt

Турист
Регистрация
29 Апр 2015
Сообщения
2
Реакции
0
Credits
7
это все многопоточная чушь
в итоге со всеми синхронизациями и прочей фигней результат будет тот же, что и без потоков + куча лаганого ненужного говнокода
выключил все сразу, заполнил и включил
 

Kelvin21

Местный
Регистрация
6 Окт 2016
Сообщения
11
Реакции
0
Credits
42
Эм, а разве нельзя использовать критические секции? Всегда ими пользовался когда нужно обратиться к форме. Либо использовать глобальные массивы по окончанию работы из которых заполнять форму. или по таймеру например. Ведь куча вариантов.
 

ForumReader

Местный
Регистрация
16 Окт 2008
Сообщения
8
Реакции
4
Credits
18
Вообще, множественная работа с GUI в потоках - тот еще геморрой, соглашусь с комментатором №11
 

protos59

Турист
Регистрация
15 Сен 2016
Сообщения
6
Реакции
0
Credits
8
VCL, насколько я понимаю, однопоточный и из разных потоков в данной задаче работать с ним смысла наверное нат. Заполняться они наверняка будут по-очереди.

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

styxozavr

Местный
Регистрация
25 Июл 2009
Сообщения
11
Реакции
68
Credits
22
Многие DAC позволяют получать данные из БД в потоках параллельно, нужно только каждому запросу предоставить отдельный коннекшн. Никаких проблем не наблюдал.
 
Последнее редактирование модератором: