Безопасно ли использовать объект TAdsSettings в основном потоке и объекты AdsQuery в других потоках?

У меня есть приложение Win-CGI, которое я сейчас конвертирую в ISAPI.

Приложение использует потомков TDataset для сервера баз данных Extended Systems Advantage.

Поскольку может быть только один экземпляр объекта TAdsSettings, он должен находиться в основном потоке.

Объекты TAdsQuery необходимы в потоках запросов.

Будет ли это работать, то есть будут ли запросы AdsQueries в потоках запросов получать глобальные настройки из объекта AdsSettings в основном потоке, и будет ли это потокобезопасным?


person Graza    schedule 18.09.2008    source источник


Ответы (3)


Да, это сработает. Компонент TAdsSettings изменяет настройки в Advantage Client Engine (ACE), а с ISAPI будет загружен один экземпляр ACE, который используют все потоки.

Однако я бы не рекомендовал его. В зависимости от настроек, которые вы меняете, имеет смысл просто вызывать API ACE напрямую. Например, если вы устанавливаете только формат даты, имеет смысл исключить компонент TAdsSettings и просто вызвать AdsSetDateFormat60, который принимает дескриптор соединения. Избавление от компонента TAdsSettings устраняет множество вызовов для установки глобальных настроек ACE. Многие из этих вызовов должны иметь объект синхронизации, чтобы удерживать все соединения, пока изменяется глобальный объект. Это отрицательно скажется на производительности, особенно в многопоточном приложении, таком как веб-приложение. Вместо этого делайте вызовы, которые работают с указанным дескриптором соединения.

Вы можете получить дескриптор соединения, обратившись к свойству TAdsConnection.Handle или вызвав метод TAdsQuery.GetAceConnectionHandle.

person Jeremy Mullin    schedule 18.09.2008

Убедитесь, что AdsQueries используют Synchronize для прямого доступа к TAdsSettings (или используйте систему обмена сообщениями для связи между рабочими потоками и основным потоком вместо прямого доступа), если они не находятся в основном потоке (например, System.MainThreadID <> Windows.GetCurrentThreadID)

person Francesca    schedule 18.09.2008
comment
В целом я согласен, синхронизация - это самый безопасный (синхронный) способ использования основного потока из дочерних потоков. (msgs лучший асинхронный способ) Однако я конкретно спрашиваю о компах ADS, а не об общей многопоточности. У Джереми есть более актуальная информация об особенностях ADS и их внутренней работе. - person Graza; 22.09.2008

Я также задавал этот вопрос в группе новостей: devzone.advantagedatabase.com, Advantage.Delphi.

Для полноты я добавлю дополнительный вопрос/ответ из остальной части этой темы:

Вопрос (я):

Многие запросы в потоках в настоящее время не привязаны к объекту TAdsConnection. Я планирую создать соединение для каждого потока для использования этих «сиротских» запросов, но это большое приложение, и это займет время. Я также почти уверен, что единственным свойством объекта TAdsSettings, отличным от значения по умолчанию, является набор типов серверов, который также можно установить в компоненте подключения, поэтому, как только все запросы будут связаны с подключениями, компонент настроек не понадобится. В качестве альтернативы я рассмотрю вызов API настроек напрямую.

Тем временем у меня есть вопрос о многопоточности и запросах без назначенного компонента соединения. Из файлов справки я заметил, что если запросы в нескольких потоках совместно используют один объект подключения, запросы будут выполняться последовательно, а не одновременно. С объектом подключения в каждом потоке это не должно быть проблемой, но меня интересуют запросы, которым не назначен объект подключения. Будут ли они считаться независимыми соединениями с точки зрения многопоточного параллелизма, или они будут считаться находящимися в одном и том же соединении и, таким образом, должны будут уступать друг другу?

Ответ (Джереми):

Вам нужно будет решить эту проблему. Они будут просто искать глобальный список соединений, чтобы найти соединение с таким же путем, и они будут использовать это соединение. Не очень хорошо в многопоточном приложении.

Таким образом, из ответа Джереми лучше всего создать хотя бы один объект TAdsConnection для каждого потока и убедиться, что все запросы привязаны к нему, иначе может произойти сериализация.

person Graza    schedule 19.11.2008