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

Вниз

Ошибка в выполнении параллельного потока   Найти похожие ветки 

 
ГореПрограммер   (2006-11-07 12:51) [0]

Здравствуйте.
есть клас:
 Tloadfon = class(TThread)
 protected
   procedure sinform;
   procedure Execute; override;
 end;

procedure tloadfon.sinform;
begin
fstart.prog1.StepIt;
end;
procedure tloadfon.Execute;
var i:integer;
begin
FreeOnTerminate := True;
for i := 0 to ar_excel.count - 1 do
 begin
   if Terminated then
     Break;
   loadip(ar_excel.zaps[i].mac,i);
   getminup(ar_excel.zaps[i].id);
   Synchronize(sinform);
 end;
end;

В момент обращения к нему, т.е.
tloadfon.create(false);

выдается ошибка базы данных:
dbExpress Error: Unknown Error Code "256"
[0x0005]: Operation Not Supported
Database Server Error: Failed to query the server.(Error "2013"; Reason "Lost connection to MySQL server during query")

если выполнять функции loadip и getminup  не в этом потоке, а просто в программе, то никаких ошибок не происходит. Подскажите пожалуйста где искать ошибку ?


 
ГореПрограммер   (2006-11-07 12:54) [1]

Да, если это имеет значение,
procedure loadip(mac:string;ind:integer);
fproc.q2.Active:=false;
fproc.q2.SQL.Clear;
fproc.q2.SQL.Add("select ip from ip_addr where mac_term="""+mac+"""");
fproc.q2.Active:=true;

после активации запроса вылетает как раз ошибка. и как я выше писал вылетает ошибка только при попытке сделать это в параллельном потоке


 
DVM ©   (2006-11-07 12:58) [2]


> ГореПрограммер   (07.11.06 12:51)  


> ar_excel

Это чаво такое и почему обращение к этой переменной может быть безопасным?


>    loadip(ar_excel.zaps[i].mac,i);
>    getminup(ar_excel.zaps[i].id);

Это чаво?


 
MetalFan ©   (2006-11-07 13:01) [3]

что есть fproc?
ты из потока к VCL компонентам лезешь...
создавай q2 в потоке)


 
ГореПрограммер   (2006-11-07 13:02) [4]


> > ar_excel

массив записей (record)

> >    loadip(ar_excel.zaps[i].mac,i);
> >    getminup(ar_excel.zaps[i].id);

procedure loadip(mac:string;ind:integer);
var i,j:integer;
begin
strex:=strex+"loadip";
fproc.q2.Active:=false;
fproc.q2.SQL.Clear;
fproc.q2.SQL.Add("select ip from ip_addr where mac_term="""+mac+"""");
fproc.q2.Active:=true;
......
function getminup(id:string):string;
begin
fproc.q2.Active:=false;
fproc.q2.SQL.Clear;
fproc.q2.SQL.Add("select min(date_up) from Jurup where Term_id="+id);
fproc.q2.Active:=true;
.....


 
ГореПрограммер   (2006-11-07 13:03) [5]


> что есть fproc?
> ты из потока к VCL компонентам лезешь...
> создавай q2 в потоке)

fproc это модуль, в котором содержится q2.
Поток создается в другом модуле


 
DVM ©   (2006-11-07 13:05) [6]


> массив записей (record)

Этот массив кем-то чем-то может быть изменен во время отработки потока?
Если да - будут глюки.

>    loadip(ar_excel.zaps[i].mac,i);
>    getminup(ar_excel.zaps[i].id);

Убирай в Synchronize()


 
MetalFan ©   (2006-11-07 13:16) [7]


> DVM ©   (07.11.06 13:05) [6]
>
> Убирай в Synchronize()


... и смысл вынесения в поток теряется)


 
ГореПрограммер   (2006-11-07 13:18) [8]


> >    loadip(ar_excel.zaps[i].mac,i);
> >    getminup(ar_excel.zaps[i].id);
>
> Убирай в Synchronize()

Спасибо, все заработало.
Вот только второй вопрос. Мне необходимо чтобы
> procedure tloadfon.Execute;

выполнилась только один раз. Каким образом её следует переписать, чтобы после прохождения цикла поток прекратил свою работу ?
пробовал так:

> procedure tloadfon.sinform;
> begin
> fstart.prog1.StepIt;
> end;
> procedure tloadfon.Execute;
> var i:integer;
> begin
> FreeOnTerminate := True;
> for i := 0 to ar_excel.count - 1 do
>  begin
>    if Terminated then
>      Break;
>    loadip(ar_excel.zaps[i].mac,i);
>    getminup(ar_excel.zaps[i].id);
>    Synchronize(sinform);
>  end;
> terminate;
> end;

не помогло, все равно цикл выполняется еще раз


 
Сергей М. ©   (2006-11-07 13:24) [9]


> Мне необходимо чтобы
> > procedure tloadfon.Execute;
>
> выполнилась только один раз


Он (этот метод) всего один раз и выполнится, вне зависимости от того что у него в "потрохах"


 
Anatoly Podgoretsky ©   (2006-11-07 13:25) [10]


> и смысл вынесения в поток теряется)

А здесь он появляется в проявлении ошибки, и разница то? Небольшая, лучше пусть работает, чем не работает. Может и потоки не нужны.


 
ГореПрограммер   (2006-11-07 13:26) [11]

Да, но в этом случае вопрос. каким образом после однократного прохождения цикла внутри метода поток "исчезал"  ?


 
MetalFan ©   (2006-11-07 13:28) [12]

а нафиг в execute terminate вызывается??
почитай про потоки плз сначала, а потом тут ахинею городи.
неплохая статья, имхо
http://forum.vingrad.ru/topic-60076.html


 
DVM ©   (2006-11-07 13:29) [13]


> однократного прохождения цикла

один оборот цикла? Убрать цикл :)

FreeOnTerminate := True;
после отработки Execute он уничтожится.


 
Anatoly Podgoretsky ©   (2006-11-07 13:30) [14]

Он и исчезает и ненужный, лишний вызов метода Terminate


 
ГореПрограммер   (2006-11-07 13:31) [15]

procedure tloadfon.sinform;
begin
loadip(ar_excel.zaps[index].mac,index);
getminup(ar_excel.zaps[index].id);
fstart.prog1.StepIt;
end;
procedure tloadfon.Execute;
var i:integer;
begin
FreeOnTerminate := True;
for i := 0 to ar_excel.count - 1 do
 begin
   if Terminated then
     Break;
   index:=i;
   Synchronize(sinform);
 end;
end;


В execute цикл проходит один раз, потом начинает заново.


 
ГореПрограммер   (2006-11-07 13:34) [16]

Пробовал так:

> procedure tloadfon.Execute;
> var i:integer;
> begin
> FreeOnTerminate := True;
> for i := 0 to ar_excel.count - 1 do
>   begin
>     if Terminated then
>       Break;
>     index:=i;
>     Synchronize(sinform);
>   end;
> showmessage("test");
> end;


showmessage не срабатывает. заканчивается цикл, тишина и потом цикла начинается заново.


 
DVM ©   (2006-11-07 13:34) [17]


> index:=i;

Это что еще? Почему меняешь из потока так смело значения переменных?


 
ГореПрограммер   (2006-11-07 13:36) [18]


> > index:=i;
>
> Это что еще? Почему меняешь из потока так смело значения
> переменных?

Извиняюсь, это я убрал уже. Результат тот же (


 
DVM ©   (2006-11-07 13:41) [19]

И все же ar_excel меняется в основном потоке или нет? Лучше создай у объекта потока поле FCount и свойство Count с доступом через критическую секцию. Так понадежнее. Хотя к количеству повторов цикла отношения это вряд ли имеет.


 
Anatoly Podgoretsky ©   (2006-11-07 13:45) [20]


> showmessage не срабатывает. заканчивается цикл, тишина и
> потом цикла начинается заново.

Происходит исключение, тихое.


 
Сергей М. ©   (2006-11-07 13:46) [21]


> showmessage не срабатывает


Его обязательно следует синхронизировать с осн.потоком.


> потом цикла начинается заново.


С чего ты взял ?


 
ГореПрограммер   (2006-11-07 13:48) [22]


> > showmessage не срабатывает. заканчивается цикл, тишина
> и
> > потом цикла начинается заново.
>
> Происходит исключение, тихое.

А каким образом диагностировать где и какая ошибка ?


 
ГореПрограммер   (2006-11-07 13:50) [23]


> > потом цикла начинается заново.
>
>
> С чего ты взял ?

procedure tloadfon.sinform;
begin
loadip(ar_excel.zaps[index].mac,index);
getminup(ar_excel.zaps[index].id);
fstart.prog1.StepIt;
end;
procedure tloadfon.Execute;
var i:integer;
begin
FreeOnTerminate := True;
for i := 0 to ar_excel.count - 1 do
 begin
   if Terminated then
     Break;
   index:=i;
   Synchronize(sinform);
 end;
fstart.prog1.Position:=0;
fstart.stat.Panels[0].Text:="Все данные загружены";
end;


После окончания заполнения прогресбара. через секунлы 2 он опять начинает заполняться. Логично что еще раз срабатывает цикл


 
DVM ©   (2006-11-07 13:52) [24]

Поставь windows.beep(500,50); в цикл


 
Сергей М. ©   (2006-11-07 13:54) [25]

Потому что процедура sinform() (в которой твой прогрессбар заполняется) у тебя  вызывается ar_excel.count раз


 
ГореПрограммер   (2006-11-07 14:04) [26]


> Потому что процедура sinform() (в которой твой прогрессбар
> заполняется) у тебя  вызывается ar_excel.count раз

логично. мне и необходимо её выполнить ar_excel.count раз. Но после выполнения её ar_excel.count раз она выполняется опять столько же и так до бесконечности


 
DVM ©   (2006-11-07 14:07) [27]


> ГореПрограммер   (07.11.06 14:04) [26]

ты бип в цикл поставил? цикл работает?


 
ГореПрограммер   (2006-11-07 14:08) [28]


> > ГореПрограммер   (07.11.06 14:04) [26]
>
> ты бип в цикл поставил? цикл работает?

Да, все тоже самое. цикл работает. и после окончания выполняется еще и еще


 
DVM ©   (2006-11-07 14:12) [29]

вообще странно, не должно быть если поток заново кто-то не создает.
поставь еще if Terminated then exit; вместо break;


 
ГореПрограммер   (2006-11-07 14:19) [30]

Поставил. ситуация таже( вызывает create один раз, после строки создания потока поставил showmessage  сообщение появляется только один раз


 
Сергей М. ©   (2006-11-07 14:25) [31]

Отладчиком умеешь пользоваться ?


 
ГореПрограммер   (2006-11-07 14:30) [32]


> Сергей М. ©   (07.11.06 14:25) [31]

Если ставлю точку остановки на следующую строку после цикла то процесс выполнения не прерывается


 
Anatoly Podgoretsky ©   (2006-11-07 14:39) [33]


> if Terminated then exit; вместо break

Смысла нет, масло масляное


 
Сергей М. ©   (2006-11-07 14:42) [34]


> fstart.prog1.Position:=0; // <--- сюда ставишь ?
> fstart.stat.Panels[0].Text:="Все данные загружены";


 
ГореПрограммер   (2006-11-07 14:47) [35]

Да, именно сюда


 
Anatoly Podgoretsky ©   (2006-11-07 14:50) [36]

> ГореПрограммер  (07.11.2006 14:19:30)  [30]

Но ты же именно это и просил, чем теперь недоволен?


 
Сергей М. ©   (2006-11-07 14:55) [37]


> FreeOnTerminate := True;
> for i := 0 to ar_excel.count - 1 do //<-- ставь брейкпойнт сюда и - вперед с песней, пошагово, с контролем происходящего после каждого шага


 
ГореПрограммер   (2006-11-07 15:01) [38]


>
> Но ты же именно это и просил, чем теперь недоволен?

Я хотел чтобы цикл выполнился один раз, а не бесконечное число раз


 
Сергей М. ©   (2006-11-07 15:03) [39]


> хотел чтобы цикл выполнился один раз, а не бесконечное число
> раз
>


Он и будет выполняться столько раз, сколько ему тобой предписано. Если найдешь и устранишь ошибки. Собственно к данному потоку это не имеет ни малейшего отношения - то же самое можно "накосячить" в любом ином потоке, в т.ч. и основном.


 
ГореПрограммер   (2006-11-07 15:11) [40]


> for i := 0 to ar_excel.count - 1 do
>  begin
>    if Terminated then
>      Break;
>    index:=i;
>    Synchronize(sinform);
>  end;

Да вроде по этому коду он должен выполнится ar_excel.count число раз. а не бесконечно



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

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

Наверх




Память: 0.56 MB
Время: 0.035 c
2-1162907359
m-kirill-2003
2006-11-07 16:49
2006.11.26
Кодировки


15-1162822278
Tirael
2006-11-06 17:11
2006.11.26
о форуме


3-1159279402
BBCHa
2006-09-26 18:03
2006.11.26
Создание шахматки


4-1152899610
TWINc
2006-07-14 21:53
2006.11.26
WinProc


11-1139553126
-=Mike=-
2006-02-10 09:32
2006.11.26
Печальное известие от Borland