Страница 1 из 1
thread safe
Добавлено: 08 ноя 2006, 12:08
bachin
Пишу свою обвертку над FB API. Хотелось бы сразу реализовать потокобезопастность. gds32 от IB в свое время страдал проблемой паралельного создания конектов в контексте библиотеки, стейтментов в контексте коннекта и т.д..
интересуют следующие вопросы:
1. осталась ли эта проблема?
2. где найти инфу по связкам обектов, которые надо лочить?
например:
Код: Выделить всё
isc_dsql_alloc_statement2(@status ,@db_handle, @stmt_handle);
Код: Выделить всё
isc_dsql_prepare(@status, @trans_handle, @stmt_handle, 0, PChar(sql), SQL_DIALECT_CURRENT, nil);
в первом случае надо лочить создание обектов в контексте базы, а во втором в контексте транзакции?
Добавлено: 09 ноя 2006, 13:26
Dimitry Sibiryakov
Еманов утверждал что достаточно сериализовать только коннекты. Ну, и, конечно, не лезть в один коннект из разных потоков.
Добавлено: 09 ноя 2006, 15:09
hvlad
Dimitry Sibiryakov писал(а):Еманов утверждал что достаточно сериализовать только коннекты. Ну, и, конечно, не лезть в один коннект из разных потоков.
Одновременно! Не лезть одновременно
Добавлено: 09 ноя 2006, 16:00
bachin
hvlad писал(а):Dimitry Sibiryakov писал(а):Еманов утверждал что достаточно сериализовать только коннекты. Ну, и, конечно, не лезть в один коннект из разных потоков.
Одновременно! Не лезть одновременно
вот и я так подумал

можно только уточнить, насколько "одновременно"?
т.е если я сделал statement.prepare->execute и идет fetch, тобишь я работаю с хендлом стейтмента, я уже могу с другого потока создавать другой стейтмент или пока все порожденные от этого коннекта объекты не закрою еще нельзя?
Добавлено: 09 ноя 2006, 17:09
hvlad
bachin писал(а):hvlad писал(а):Dimitry Sibiryakov писал(а):Еманов утверждал что достаточно сериализовать только коннекты. Ну, и, конечно, не лезть в один коннект из разных потоков.
Одновременно! Не лезть одновременно
вот и я так подумал

можно только уточнить, насколько "одновременно"?
Нельзя одновременно вызывать API для одного database handle в двух потоках
Добавлено: 09 ноя 2006, 18:21
bachin
hvlad писал(а):Нельзя одновременно вызывать API для одного database handle в двух потоках
я еще немного уточну...
с критикал секцией с контексте db handle:
transaction -> start, commin, rollback
statement -> create
без критикал секции:
statement -> prepare, execute, fetch, free, describe_bind, describe
(блобы пока не рассматриваем)
Добавлено: 13 ноя 2006, 12:50
bachin
hvlad писал(а):[Нельзя одновременно вызывать API для одного database handle в двух потоках
даж и незнаю что сказать...
погонял стресс тестирование
100 000 потоков, через каждую 1000 слип на секунду (а то у винды крыша едет - не умеет она столько потоков открывать)
все работают в одном коннекте.
операции простые - создал транзакцию, создал стейтмент, сбиндил инпут параметры, экзекюте, фетч, аутпут, закрыл стейтмент, закрыл транзакцию....
никаких критикал сэкшн и никаких накладок.
может кто точно сказать, где всетаки идет конкурентный доступ нуждающийся в разруливании на клиенте....
Добавлено: 20 ноя 2006, 15:59
aaa3d
наталкиваю на мысль.
Предполагаю что комп у тебя однопроцессорный.
у тебя потоков много, но в один момент времени работает только ОДИН.
соответственно кое-какое временное разруливание получается на уровне операционки.
прогони свой тест на двухядерной машинке, наверняка что нить упадет.
Добавлено: 21 ноя 2006, 10:59
bachin
aaa3d писал(а):наталкиваю на мысль.
Предполагаю что комп у тебя однопроцессорный.
у тебя потоков много, но в один момент времени работает только ОДИН.
соответственно кое-какое временное разруливание получается на уровне операционки.
на самом деле, работа со списками не атомарная задача и для получения gpf не требуется многопроцессорная тачка... но дело даже не в этом, вопрос стоял по-другому, какие обекты требуют конкурентного доступа и какие эксклюзивного.
Добавлено: 29 ноя 2006, 10:47
malefik
Господа! Сам наткнулся на грабли (с несколькими потоками) ......однако прочитав ваши посты все встало более менее понятно.....НО....хотелось бы прояснить ситуацию и получить четкие ответы....ЕСЛИ ВАС НЕ ЗАТРУДНИТ!
Вобщем...у меня создаются несколько нитей Tthread ....в каждой нитке создаются объекты для работы с базой...
Код: Выделить всё
_query = new TpFIBQuery(mainForm->FIBDatabase);
_transaction = new TpFIBTransaction(mainForm->FIBDatabase);
затем присваиваем соответствующие свойства ....для работы на один компонент FibDatabase который находится в основной нити приложения т.е. лежит на форме.
вобщем периодически все это хозяйство падает......теперь уже знаю почему.....
Вопрос .....как можно организовать нормальную работу......? Использование метода Synchronize ? даст положительные результаты?
Если да то что туда затолкать ? старттранзакшн....екзецкуэри....коммит.....? либо все??? Как это скажется на работе основной нити приложения.....?? она при долгих ожиданиях будет останавливатся?потоков в приложении у меня может быть не одна сотня.....А может организовывать отдельный коннект для каждой нити ......это будет изврат...? Как порекомендуете разрешить данную проблему? Спасибо! Надеюсь на помощь....
P.S. Проц у меня действительно 2х ядерный
Добавлено: 29 ноя 2006, 11:00
kdv
А может организовывать отдельный коннект для каждой нити ......это будет изврат...?
это не изврат, это FAQ.
www.ibase.ru/ibfaq.htm