Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2003.02.17;
Скачать: [xml.tar.bz2];

Вниз

Проблема с тредами.   Найти похожие ветки 

 
Vovaka   (2003-02-07 14:09) [0]

Столкнулся с проблемой, есть несколько тредов. Когда в одном из них выполняется Query.Open с громоздким запросом, то во время выполнения этого запроса все остальные треды и главный процесс отдыхают т.е. чего-то ждут, а чего не понятно. В общем приложение не отвечает на запросы пока не закончится выполнение запроса. В чем может быть дело ?


 
Digitman   (2003-02-07 14:19) [1]

быть того не может ... даже если тред с idle-приоритетом

наверняка, не в доп.треде у тебя запрос выполняется, а в основном)


 
Smithson   (2003-02-07 14:33) [2]

Sychronize?


 
Vovaka   (2003-02-07 14:48) [3]

Основной процесс

procedure TMainForm.MainTimerTimer(Sender: TObject);
var
DBProcessingMoment : TdateTime;
begin
MainTimer.Enabled := false;
StatusBar1.Panels[2].Text := "*";
if NoConnect then
begin
AddToLog(1, "БД недоступна.");
MainTimer.Enabled := true;
StatusBar1.Panels[2].Text := "";
Exit;
end;

Query1.Close;
Query1.SQL.Clear;
Query1.SQL.Add("select now()");
try
Query1.Open;
except
MainTimer.Enabled := true;
StatusBar1.Panels[2].Text := "";
Exit;
end;
ProcessingMoment := Query1.Fields[0].AsDateTime;
Query1.Close;

if LostCalls then
begin
if ServProcess1 = nil then
ServProcess1 := TServ.Create(1, ProcessingMoment) // Удаление зависших звонков
else
if ServProcess1.Suspended then
ServProcess1.Resume;
end;

if LostSessions then
begin
if ServProcess2 = nil then
ServProcess2 := TServ.Create(2, ProcessingMoment) // Удаление зависших сессий
else
if ServProcess2.Suspended then
ServProcess2.Resume;
end;

if ServProcess3 = nil then
ServProcess3 := TServ.Create(3, ProcessingMoment) // Универсальная статистика
else
if ServProcess3.Suspended then
begin
ServProcess3.ProcessingTime := ProcessingMoment;
ServProcess3.Resume;
end;

if AgentsAlarms then
begin
if ServProcess4 = nil then
ServProcess4 := TServ.Create(4, ProcessingMoment) // Сообщения от агентов
else
if ServProcess4.Suspended then
ServProcess4.Resume;
end;

Query1.Close;
Query1.SQL.Clear;
Query1.SQL.Add("select * from Synchro.SynchroTasks where TaskTime <= """ + FormatDateTime("yyyy-mm-dd hh:nn:ss", ProcessingMoment) + """");
try
Query1.Open;
except
MainTimer.Enabled := true;
StatusBar1.Panels[2].Text := "";
Exit;
end;
while not Query1.Eof do
begin
DBProcessingMoment := Query1.Fields[2].AsDateTime;
if TaskBusy[Query1.Fields[0].AsInteger] then
begin
Query1.Next;
Continue;
end;

case Query1.Fields[0].AsInteger of
5: TServ.Create(5, ProcessingMoment); // Детектор петель
6: TServ.Create(6, ProcessingMoment); // Ошибки маршрутизации
.......
39: TServ.Create(39, DBProcessingMoment); // Dial-Up мин. платежи и абон. платы
else
AddToLog(1, "Неизвестная процедура [" + Query1.Fields[0].AsString + "]");
end;
Application.ProcessMessages;
Query1.Next;
end;
Query1.Close;

StatusBar1.Panels[2].Text := "";

MainTimer.Enabled := true;
end;


 
Vovaka   (2003-02-07 14:50) [4]

Тред

procedure TServ.Execute;
begin
FinishFlag := false;

while true do
begin
try
MainDataBaseOpen;
except
end;
if NoConnectMain then Break;

if Mode in [5, 6, 26, 27, 28, 30, 31, 32, 33, 34, 35] then
begin
try
StatDataBaseOpen;
except
end;
if NoConnectStat then Break;
end;

try
case Mode of
1: ClearLostCalls;
2: ClearLostSessions;
3: ProcessUniStat;
4: ProcessAgentAlarms;
5: ProcessDoubleCallsAlarms;
6: ProcessCheckDialPlan;
.......
39: ProcessDialUpMonthPayments;
else
_Mes := "Неизвестная процедура";
_IsOk := 1;
AddToLog;
end;
except
on E : Exception do
begin
_Mes := Trim("Ошибка при выполнении процедуры. [" + IntToStr(Mode) + "] " + E.Message);
_IsOK := 1;
AddToLog;
end;
end;
if (Mode in [1, 2, 3, 4]) and not FinishFlag then
Suspend
else
Break;
end;

MainDataBaseClose;
StatDataBaseClose;
end;

constructor TServ.Create(_Mode : integer; _DT : TDateTime);
begin
Inherited Create(true);
FreeOnTerminate := true;
Priority := tpLower;

Mode := _Mode;
ProcessingTime := _DT;
Inc(ThreadNum);
Inc(ThreadCount);
IndividualNumber := ThreadNum;
DataBaseName := "i" + IntToStr(IndividualNumber) + "n";
TaskBusy[_Mode] := true;
MainDataBase := nil;
StatDataBase := nil;
Query1 := nil;
Query2 := nil;
StatQuery1 := nil;
StatQuery2 := nil;
Resume;
end;

Как пример одна из процедур

procedure TServ.ProcessDoubleCallsAlarms;
var
Dt : String;
MaxDT : TDateTime;

begin
if DoubleCalls then
begin
SQLOpenStat("select max(Dt) from "voip".Calls");
MaxDt := StatQuery1.Fields[0].AsDateTime;

SQLOpen("select Value from "dba".SysVariable where Name = ""LastDoubleCallsCheck""");
Dt := Query1.Fields[0].Asstring;

SQLOpenStat("select dt, e164Number, Duration, count(*) as c from "voip".Calls where dt > """ + Dt +
""" and Duration > 30 group by dt, e164Number, Duration having c > 1 order by 4 desc");

while not StatQuery1.EOF do
begin
SQLExec("insert into dba.SystemMessage values(default, 13, now(*),""Обнаружена петля."",""" +
"Обнаружены петлевые звонки: " +
"Дата/время : " + StatQuery1.Fields[0].asString + " " +
"Номер : " + StatQuery1.Fields[1].asString + " " +
"Длительность : " + StatQuery1.Fields[2].asString + """)");
StatQuery1.Next;
end;
StatQuery1.Close;

SQLExec("update "dba".SysVariable set Value = """ + FormatDateTime("yyyy-mm-dd hh:nn:ss.zzz", MaxDT) + """ where Name = ""LastDoubleCallsCheck""");
end;

SQLExec("update synchro.SynchroTasks set TaskTime = """ + FormatDateTime("yyyy-mm-dd hh:nn:ss", IncMinute(ProcessingTime, 10)) + """ where ID = 5");
end; { ProcessDoubleCallsAlarms }

И пока выполняется SQLOpenStat("select dt, e164Number, Duration, count(*) as c from "voip".Calls where dt > """ + Dt +
""" and Duration > 30 group by dt, e164Number, Duration having c > 1 order by 4 desc");

все везде стоит...



 
Vovaka   (2003-02-07 14:55) [5]

Ни одного Synchronize нет, остановка всех процессов происходит именно в момент выполнения запроса, я делал дебаггинг, каждый тред писАл в свой лог, было видно, что перед выполнением запроса строчка попала в лог, после запроса строчка появилась через несколько минут и во логах других тредов в этот период ни одной записи


 
Digitman   (2003-02-07 15:16) [6]

мне очень не нравится то, что в обработчике MainTimerTimer() выполняются какие-то запросы ...

на основании чего ты уверен, что Query1.Open в любом случае выполнится мгновенно ?


p.s.

разберись с терминологией

есть некое приложение, при его старте система организует процесс, ассоциированный с приложением, и после создания процесса системой создается ОСНОВНОЙ ТРЭД этого процесса

некорректно говорить - ОСНОВНОЙ ПРОЦЕСС


 
Vovaka   (2003-02-07 15:24) [7]

Терминология хромает ;)

по поводу Query1.Open в обработчике MainTimerTimer(), как время его выполнения может на что-то повлиять в дополнительных потоках ? Там же создаются свои Query.


 
Ihor Osov'yak   (2003-02-07 16:50) [8]

С исходного кода не все понятно.

Попытаюсь дать наводки на потенциальные проблемы.

Не понятно, где создаются сами запросы, что юзаются SQLOpenStat,
через какой коннект работают. Вполне возможно, что для каждого паралельно выполняемого запроса нужен свой коннект (с вашего исходника не понятно, какой движок доспупа к базе используется). По поводу создания запросов - вполне возможно, что вы создаете их в основном потоке, ну а если в компоненте-надстройке над запросом используется какая-то передача сообщений, то эти сообщения будут обрабатыватся в основном потоке, а не вашем - одним словом, вы, вполне возможно, получаете где-нибуть неявную синхронизацию вследствии посылки SendMessage окну, созданном в другом потоке ...
Да и мало чего может быть.. Нужен полный код для достоверного анализа. Но код, судя по всему, большой - следовательно, анализ будет делать влом...


 
Digitman   (2003-02-07 16:52) [9]

пока я веду речь о "некрасивостях" в осн.трэде процесса

ты же сам пишешь

"приложение не отвечает на запросы пока не закончится выполнение запроса"

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


 
Vovaka   (2003-02-07 17:05) [10]

Проблема побеждена после того как в каждом треде помимо создания DataBase и Query стал создаваться Session и прописываться у DataBase и у Query.

Спасибо всем отклинувшимся.


 
Digitman   (2003-02-07 17:15) [11]

Здрасть !

так ты тут лапшу на уши вешал, оказывается)

у тебя не "вис" поток. а - рушился !



 
Vovaka   (2003-02-07 17:19) [12]

Почему рушился ? Все же нормально продолжало потом работать :)


 
Digitman   (2003-02-07 17:25) [13]

база-то какая ?


 
Vovaka   (2003-02-07 17:26) [14]

sybase adaptive server anywhere 7


 
Digitman   (2003-02-07 17:36) [15]

ну не знаю уж как в Sybase, но в IB этот фокус вряд ли прошел бы безболезненно

а вообще первое правило при пользовании того же BDE (с мультипоточным доступом к НД) - отдельная сессия и отдельный коннект на каждый трэд



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

Форум: "Основная";
Текущий архив: 2003.02.17;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.015 c
1-52939
Yarmak_Sergey
2003-02-08 13:10
2003.02.17
Разработка компонента


3-52753
Dead Stark
2003-01-29 17:24
2003.02.17
Есть ли групповая функция перемножения?


1-52879
DimonZh
2003-02-05 21:27
2003.02.17
Кто-нибудь работал с Project->Languages?


1-52869
Шоломицкий
2003-02-07 17:12
2003.02.17
Регионы форм!!!!!!!


1-52940
NewGuest
2003-02-08 23:35
2003.02.17
Пожалуйста, ответьте кто работал с dxBarManager!!!





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский