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

tarakan19832

Турист
Подскажите, пожалуйста, на моем примере как правильно синхронизировать несколько потоков.
На форме есть 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

Турист
попробуй создать на каждый комбо , отдельный поток ? или у тебя там их мильён ?
 

LeshaRB

Завсегдатай
Staff member
Moderator
Как выполнить N операций M потоками, как-то так я бы гуглил
 

dustypup

Турист
Создай несколько экземпляров потока.
Передай в каждый поток указатель на свой комбобокс.
В потоке заполняй комбобокс и enable его.
Запускай все потоки одновременно.
 

fets

Турист
synchronize используется для GUI, для синхронизации действий, лучше использовать симофоры, пока действие не будет сделано семафор дальше не пустит:

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

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

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

tarakan1983

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

Earl_Vadim

Турист
Нет. я не профессионал.. все сам ищу через поиск.
Суть mutex - тотже симафор... просто поиском вы больше инфы найдете по слову mutex, чем по слову Semaphore ..

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

[HIDE]http://forum.vingrad.ru/forum/topic-60076.html [/HIDE]

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

alchemist131

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

Keoda

Турист
Если у тебя доступ к базе данных на чтение открыт свободно, я бы сделал потоки для каждого комбобокса:
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) {включить все комбы}
 
Last edited by a moderator:

robt

Турист
это все многопоточная чушь
в итоге со всеми синхронизациями и прочей фигней результат будет тот же, что и без потоков + куча лаганого ненужного говнокода
выключил все сразу, заполнил и включил
 

Kelvin21

Турист
Эм, а разве нельзя использовать критические секции? Всегда ими пользовался когда нужно обратиться к форме. Либо использовать глобальные массивы по окончанию работы из которых заполнять форму. или по таймеру например. Ведь куча вариантов.
 

ForumReader

Турист
Вообще, множественная работа с GUI в потоках - тот еще геморрой, соглашусь с комментатором №11
 

protos59

Турист
VCL, насколько я понимаю, однопоточный и из разных потоков в данной задаче работать с ним смысла наверное нат. Заполняться они наверняка будут по-очереди.

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

styxozavr

Турист
Многие DAC позволяют получать данные из БД в потоках параллельно, нужно только каждому запросу предоставить отдельный коннекшн. Никаких проблем не наблюдал.
 
Last edited by a moderator:
Top