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

йцукеурщл

Местный
Регистрация
30 Май 2014
Сообщения
13
Реакции
3
Credits
24
нужно только каждому запросу предоставить отдельный коннекшн
очень смешно
это кто додумался до такого?

для многопоточных запросов нужно в самом query выставить тип Asynchrone
или в одном подключении запустить многопоточный TTHeread

1 connection - 1 запрос это очень не то
 

styxozavr

Местный
Регистрация
25 Июл 2009
Сообщения
11
Реакции
68
Credits
22
это кто додумался до такого?

цитата из мануала FireDAC написал(а):
A connection object and all objects associated with it (such as TFDQuery, TFDTransaction, and so on) are used by a single thread at each moment.
Иными словами: для того, чтоб запросы работали асинхронно, необходимо каждому предоставить свой коннект.
 

protos59

Турист
Регистрация
15 Сен 2016
Сообщения
6
Реакции
0
Credits
8
очень смешно
это кто додумался до такого?

для многопоточных запросов нужно в самом query выставить тип Asynchrone
или в одном подключении запустить многопоточный TTHeread

1 connection - 1 запрос это очень не то

А что не так? Речь идет о параллельном выполнении. Известные мне СУБД не умеют через одно соединение выполнять одновременно несколько запросов. Со стороны delphi можно использовать пул соединений, который скроет создание нескольких соединений.
 

Zhrnya

Турист
Регистрация
6 Май 2010
Сообщения
7
Реакции
0
Credits
12
обявляешь
CRITICAL_SECTION _USEVCL;

..................
..................
инициализируешь
InitializeCriticalSection(&_USEVCL);


потом пользуешься в каждом потоке. Обрамляешь конкурирующие действия в EnterCriticalSection и LeaveCriticalSection.

EnterCriticalSection(&__USEVCL);
критичные код
LeaveCriticalSection(&__USEVCL);

тут главное не забывать делать leave.
 

test1c

Местный
Регистрация
25 Июл 2010
Сообщения
20
Реакции
5
Credits
36
Я попробую предложить самый простой вариант.
В модуле формы локальную переменную-счетчик. при старте ставим его в 0.
В "Синхронайз" каждого потока увеличивать этот счетчик и проверять, если он равен количеству комбобоксов сделать все комбо доступными.
 

yyjksw

Местный
Регистрация
17 Июл 2008
Сообщения
20
Реакции
6
Credits
26
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

Турист
Регистрация
14 Июл 2009
Сообщения
4
Реакции
2
Credits
8
В основном потоке нужно задизэйблить все элементы UI, создать поток обновления для каждого элемента UI, каждый поток должен по окончанию послать событие на enable. Но комментатор N11 всё равно прав. Выиграш будет нулевой, в большинстве случаев станет только хуже.
 

vegebi

Турист
Регистрация
22 Мар 2017
Сообщения
5
Реакции
2
Credits
10
Я попробую предложить самый простой вариант.
В модуле формы локальную переменную-счетчик. при старте ставим его в 0.
В "Синхронайз" каждого потока увеличивать этот счетчик и проверять, если он равен количеству комбобоксов сделать все комбо доступными.

При использовании такого способа следует указать атрибут Volatile для счётчика и можно будет обойтись без Synchronize для работы с ним:
Для просмотра ссылки Войди или Зарегистрируйся

В свежих версиях Delphi появились библиотека Parallel Programming Library, которая упрощает запуск нескольких заданий в отдельных потоках и их синхронизацию с основным потоком:
Для просмотра ссылки Войди или Зарегистрируйся
Для просмотра ссылки Войди или Зарегистрируйся
 

X-Cite!

Местный
Регистрация
24 Мар 2014
Сообщения
25
Реакции
5
Credits
55
Подскажите, пожалуйста, на моем примере как правильно синхронизировать несколько потоков.
На форме есть 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

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

falsenull

Турист
Регистрация
2 Май 2017
Сообщения
1
Реакции
0
Credits
2
Какая версия Delphi?
Если не очень старая, стоит посмотреть в сторону TTask - там легко управлять пулом потоков
 

kefeka

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