Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.12.19;
Скачать: CL | DM;

Вниз

ADO в потоках   Найти похожие ветки 

 
Vilux ©   (2004-11-23 13:28) [0]

В потоке пускаю dll, которая подключается к аксессовской базе и выполняет запрос. Но если создать много потоков, то все "падает". Если убрать процедуру подключения к базе, то все работает нормально. Пробовал в этой dll использовать CoInitialize(nil) и  CoUnInitialize, но не помогает...:( какие еще мысли и советы есть?


 
KSergey ©   (2004-11-23 13:34) [1]

Надо
а) Либо в каждом потоке ходить через свой коннект
б) Либо если используется 1 коннект - то запросы выполнять раздельно для каждого топока.

ADO не поддерживает потокобезопасный доступ через один коннект к базе. Либо я чего-то не знаю ;)


 
Vilux ©   (2004-11-23 13:47) [2]

Вот что я делаю в dll-ке... т.е. получается, что я создаю каждый раз свой коннект...другой вопрос, когда я запускаю dll-ку в потоке, то для каждого потока dll-ка отдельно грузится?В потоке я делаю так hinstDLL := LoadLibrary(pchar(dllname)); и вроде как в каждом потоке значение hinstDLL одно и то-же... так и должно быть?
А вот как делаю в dll-ке
try
CoInitialize(nil);
ado:=TADOConnection.Create(nil);
ado.ConnectionString:="Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+sc_base+";Persist Security Info=False";
ado.LoginPrompt:=false;
ado.Open;
q:=TAdoQuery.create(nil);
q.Connection:=ado;
q.SQL.Text:=format(
"select HelpF from TKey where Page=""%s"""
,[page]);
q.Open;
result:="";
if q.RecordCount>0 then
 result:=q.fieldbyname("HelpF").AsString;
q.Close;
q.free;
ado.Close;
ado.Free;
CoUninitialize;
except
log("Error in GetHelp function");
end;


 
KSergey ©   (2004-11-23 13:51) [3]

> [2] Vilux ©   (23.11.04 13:47)
> А вот как делаю в dll-ке

В смысле этот код вызывается из функции потока? Если да - то не наю что тут сказать...
Кстати, падает без диагностики?
И еще. А может dll-ку все же не в потоке грузить, а? Зачем? Может ее один раз загрузить - а в потоках уже ф-цию из нее вызывать?


 
Vilux ©   (2004-11-23 13:58) [4]

1.Поподробнее...
в цикле создается, допустим, 100 потоков...
в каждом потоке в память подгружается dll-ка и вызывается функция из нее, которая работает с базой...вот и все
2.Если я в самом начале подгружу dll-ку, и буду в каждом потоке вызывать ее функцию, то как раз получится, что мне придется делать это по очереди. Тогда пропадает весь смысл многопоточности. А если в каждом потоке подгружается dll-ка, то по идее все должно работать, но на практике не работает :(


 
Digitman ©   (2004-11-23 14:14) [5]

DLL грузится в АП процесса лишь при первом успешном обращении к LoadLibrary(), неважно из какого трэда сделланном.

при всех последующих обращениях к LoadLibrary() для той же DLL лишь увеличивается на 1-цу сч-к ссылок на эту библ-ку, а сама загрузка не происходит - образ модуля и так уже находится в АП процесса

при каждом FreeLibrary() для этой DLL (неважно из какого треда произошел этот вызов) на 1-цу уменьшается сч-к ссылок на эту библ-ку, и библиотека будет выгружена системой, как только сч-к станет равен 0.


> Если убрать процедуру подключения к базе, то все работает
> нормально


как же твой запрос выполнится, если "убрать процедуру подключения" ?


 
Vilux ©   (2004-11-23 14:19) [6]

так как мне быть то? ведь если из кучи потоков обращаться одноверменно к функции, которая расположена под одному и тому же адресу, тогда ведь косяки пойдут? или я не прав? как мне сделать, чтобы в каждом потоке существовала своя функция?


 
KSergey ©   (2004-11-23 14:24) [7]

> [6] Vilux ©   (23.11.04 14:19)
> так как мне быть то? ведь если из кучи потоков обращаться
> одноверменно к функции, которая расположена под одному и
> тому же адресу, тогда ведь косяки пойдут? или я не прав?
> как мне сделать, чтобы в каждом потоке существовала своя
> функция

Не прав. Каждая функция существует в каждой программе один единственный раз по определению.


 
Vilux ©   (2004-11-23 14:29) [8]

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


 
Digitman ©   (2004-11-23 14:30) [9]


> если из кучи потоков обращаться одноверменно к функции,
> которая расположена под одному и тому же адресу


с какого перепугу адрес ф-ции изменится-то ?

try
CoInitialize(nil);
ado:=TADOConnection.Create(nil);
ado.ConnectionString:="Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+sc_base+";Persist Security Info=False";
ado.LoginPrompt:=false;
ado.Open;
q:=TAdoQuery.create(nil);
q.Connection:=ado;
q.SQL.Text:=format(
"select HelpF from TKey where Page=""%s"""
,[page]);
q.Open;
result:="";
if q.RecordCount>0 then
result:=q.fieldbyname("HelpF").AsString;
q.Close;
q.free;
ado.Close;
ado.Free;
CoUninitialize;
except
log("Error in GetHelp function");
end;


> косяки пойдут? или я не прав?


ты не прав, называя "косяками" то чего не понимаешь.
никаких "косяков" нет и быть не может.


> как мне сделать, чтобы в каждом потоке существовала своя
> функция?


галиматья.
функция - это в конечном итоге фрагмент машкода.
этот самый фрагмент машкода начинает фигурировать в АП процесса при ПЕРВОМ же успешном результате явного/неявного выполнения LoadLibrary(), неважно в контексте какого трэда сделанного.


 
Vilux ©   (2004-11-23 14:35) [10]

:( ладно...более-менее разобрался. Только вот не понял, почему же в таком случае программы вылетает.Учитывая то, что если убрать работу с БД, то все работает


 
Vilux ©   (2004-11-23 14:36) [11]

Ведь каждый раз при вызове указанной выше процедуры создается новый ADOConnection  и т.п. Почему криво работает...


 
sniknik ©   (2004-11-23 14:41) [12]

> Только вот не понял, почему же в таком случае программы вылетает.
ado, q переменные локальные или глобальные?

result:=q.fieldbyname("HelpF").AsString;
при создании dll внимательно предупреждение читал, которое там выдается?

и т.д. глюк как всегда в другом. ;о))


 
Vilux ©   (2004-11-23 14:49) [13]

да, вот, сразу надо было написать

function GetHelp:string;
var ado:TAdoConnection;
q:TAdoQuery;
begin
---то что выше
end;
т.е. переменные локальные.
Попробовал сейчас один раз только грузить dll и передавать адрес процедуры в каждый поток. result пока убрал...все равно вылетает. Причем просто исчезает процесс, без всяких мессаг. Был и не стало.


 
Digitman ©   (2004-11-23 14:59) [14]

пробовал так, пробовал сяк ...

прямо-таки - басня Крылова про мартышку и очко.

галиматья.
при полном непонимании.

вообще-то есть встр.отладчик, на то и предназначенный, чтобы онять причину неверной работы программы.


 
sniknik ©   (2004-11-23 15:04) [15]

> result пока убрал...все равно вылетает.
зачем? тогда убирай все что со строками работает, иначе смысла нет. (или всетаки прочитать предупреэжение)


 
Vilux ©   (2004-11-23 15:05) [16]

2Digitman, ну и как мне поможет отладчик при отладке потоков?
И я не спорю, что все понимаю, по-крайней мере пытаюсь найти ответы на этом форуме.


 
Vilux ©   (2004-11-23 15:11) [17]

sniknik, какое предупреждение и где его можно прочитать?


 
sniknik ©   (2004-11-23 15:30) [18]

когда делаеш dll новую оно прямо в начале комментарием вставляется.


 
Digitman ©   (2004-11-23 15:33) [19]


> Vilux ©   (23.11.04 15:05) [16]
> ну и как


каком кверху.
отладчик на то, вообще-то, и существует, чтобы искать ошибки в алгоритме.
и не важно, в каком потоке исполняется код с алгоритм.ошибкой - отладчик и это предусматривает.



Страницы: 1 вся ветка

Текущий архив: 2004.12.19;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.032 c
1-1102349535
avsam
2004-12-06 19:12
2004.12.19
ASCII UTF-8 ANSI


3-1100778871
TAN_K
2004-11-18 14:54
2004.12.19
Запрос - кол-во записей по условию


14-1101623392
SergP.
2004-11-28 09:29
2004.12.19
P-IV & Oracle


14-1099581539
olookin
2004-11-04 18:18
2004.12.19
Прогнозы на 5-й тур Лиги Чемпионов


14-1101813041
Dmitry_
2004-11-30 14:10
2004.12.19
!