Форум: "Базы";
Текущий архив: 2004.12.19;
Скачать: [xml.tar.bz2];
Вниз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;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.032 c