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

Вниз

Thread (проблема завершения 3 потока)   Найти похожие ветки 

 
kaharin ©   (2007-08-30 23:44) [0]

Суть проблемы в следующем
есть основной поток (1) из него запускается дополнительный поток (2) который собирает данные из базы (список транзакций для отправки). Так как транзакции должны уходить в разные места то во втором потоке динамически создаются еще n.. количество потоков (до 50) и они отпускаются в свободное плаванье (не пересекаясь). Так вот если я останавливаю по флагу поток номер 2 то у меня какая то часть динамических потоков как бы вылетают (перестают работать) Вопрос если у потоков такое понятие как "папа" и если да то как сделать так что у динамических потоках папа был не создатель потока а основной поток программы

пример кода:

запуск 2 потока

procedure TSQL.Execute;
var
Goend_flag:boolean;
label Pause;
label Work;
label Goend;
label Start;
begin
RaningPotoks:=0;
while not Terminated do
begin
try
fMonDirMain.TOPUP_Query.Close;
fMonDirMain.TOPUP_Query.Open;
Goend_flag:=false;
except
fMonDirMain.lbLog.Items.Add("Îøèáêà ïðè îáðàùåíèè ê áàçå äàííûõ");
Goend_flag:=true;
end;
if Goend_flag=true then goto Goend;
RecordsInZapros:=fMonDirMain.TOPUP_Query.RecordCount;

if fMonDirMain.lbLog.Items.Count > 100 then fMonDirMain.lbLog.Items.Clear;

if not fMonDirMain.TOPUP_Query.IsEmpty then
       begin
       fMonDirMain.TOPUP_Query.DisableControls;
       fMonDirMain.TOPUP_Query.First;

       While not (fMonDirMain.TOPUP_Query.Eof) do
               begin
               if stop=true then
                       BEGIN
                       fMonDirMain.TOPUP_Query.EnableControls;
                       fMonDirMain.TOPUP_Query.Close;
                       Application.ProcessMessages;

                       self.Terminate;
                       exit;
                       END;

               if RaningPotoks = MaxThread then goto Pause else goto Work;

               Pause:
               repeat
               Application.ProcessMessages;
               Sleep(100);
               if stop=true then
                       begin
                       fMonDirMain.TOPUP_Query.EnableControls;
                       self.Terminate;
                       exit;
                       end;
               until (RaningPotoks < MaxThread);

               Work:
               RaningPotoks:=RaningPotoks+1;
               fMonDirMain.sbMain.Panels[3].Text:="&#192;&#234;&#242;&#232;&#226;&#237;&#251;&# 229; &#231;&#224;&#239;&#240;&#238;&#241;&#251;: "+IntTOStr(RaningPotoks);

               Sleep(100); // создание и запуск динамических потоков TMonDirThread.Create(fMonDirMain.TOPUP_Query.FieldByName("PK_PAYMENT_ID").AsStri ng,  //id
                                                               fMonDirMain.TOPUP_Query.FieldByName("SYSTEM_REF").AsString, // &#234;&#238;&#228; &#243;&#241;&#239;&#229;&#248;&#237;&#238;&#227;&#238; &#239;&#235;&#224;&#242;&#229;&#230;&#224;
                                                               fMonDirMain.TOPUP_Query.FieldByName("FK_TOPUP_REQUEST_CODE").AsString, // &#234;&#238;&#228; &#238;&#248;&#232;&#225;&#234;&#232; &#239;&#240;&#238;&#226;&#224;&#233;&#228;&#229;&#240;&#224; &#239;&#240;&#232; &#239;&#240;&#238;&#226;&#229;&#228;&#229;&#237;&#232;&#232;
                                                               fMonDirMain.TOPUP_Query.FieldByName("FK_TOPUP_RESULT_ID").AsString,   // &#234;&#238;&#228; &#239;&#235;&#224;&#242;&#229;&#230;&#224; &#226; &#225;&#224;&#231;&#229; &#239;&#240;&#238;&#226;&#224;&#233;&#228;&#229;&#240;&#224;
                                                               fMonDirMain.TOPUP_Query.FieldByName("FK_SUPPLIER_ID").AsString,     // &#234;&#238;&#228; &#242;&#229;&#240;&#236;&#232;&#237;&#224;&#235;&#224;
                                                               fMonDirMain.TOPUP_Query.FieldByName("FK_PROVIDER_ID").AsString,    // &#234;&#238;&#228; &#239;&#240;&#238;&#226;&#224;&#233;&#228;&#229;&#240;&#224;
                                                               fMonDirMain.TOPUP_Query.FieldByName("SYSTEM_TIME_END").AsString,   // &#228;&#224;&#242;&#224; &#238;&#234;&#238;&#237;&#247;&#224;&#237;&#232;&#255; &#243;&#241;&#239;&#229;&#248;&#237;&#238;&#227;&#238; &#239;&#240;&#238;&#226;&#229;&#228;&#229;&#237;&#232;&#255;
                                                               fMonDirMain.TOPUP_Query.FieldByName("AMOUNT").AsString,          //&#241;&#243;&#236;&#236;&#224; &#226;&#237;&#229;&#241;&#229;&#237;&#237;&#251;&#245; &#228;&#229;&#237;&#229;&#227;
                                                               fMonDirMain.TOPUP_Query.FieldByName("SUM_COMMISSION").AsString,   // &#241;&#243;&#236;&#236;&#224; &#234;&#238;&#236;&#232;&#241;&#241;&#232;&#232;
                                                               fMonDirMain.TOPUP_Query.FieldByName("ACCOUNT_NUMBER").AsString,   // &#232;&#237;&#228;&#232;&#244;&#232;&#234;&#224;&#242;&#238;&#240;1
                                                               fMonDirMain.TOPUP_Query.FieldByName("CONTRACT_NUMBER").AsString,  // &#232;&#237;&#228;&#232;&#244;&#232;&#234;&#224;&#242;&#238;&#240;2
                                                               fMonDirMain.TOPUP_Query.FieldByName("CONTACT_DETAILS").AsString,   // &#232;&#237;&#228;&#232;&#244;&#232;&#234;&#224;&#242;&#238;&#240;3
                                                               fMonDirMain.TOPUP_Query.FieldByName("FIO").AsString,               // // &#232;&#237;&#228;&#232;&#244;&#232;&#234;&#224;&#242;&#238;&#240;4 &#232;&#235;&#232; &#212;&#200;&#206;
                                                               fMonDirMain.TOPUP_Query.FieldByName("MONTH_YEAR").AsString,         // &#238;&#239;&#235;&#224;&#242;&#224; &#231;&#224; &#239;&#229;&#240;&#232;&#243;&#228;
                                                               fMonDirMain.TOPUP_Query.FieldByName("SLIP_ID").AsString,        // &#237;&#238;&#236;&#229;&#240; &#247;&#229;&#234;&#224;
                                                               fMonDirMain.TOPUP_Query.FieldByName("SLIP_TIME").AsString){)};     // &#228;&#224;&#242;&#224; &#247;&#229;&#234;&#224;

               fMonDirMain.TOPUP_Query.Next;
               end;
        fMonDirMain.TOPUP_Query.EnableControls;
       end;
Goend:;
end;


 
kaharin ©   (2007-08-30 23:46) [1]

Продолжение от автора

создание и запуск динамических потоков
procedure TMonDirThread.Execute;
var
 HandleChange: THandle;  //Handle &#241;&#238;&#231;&#228;&#224;&#226;&#224;&#229;&#236;&#238;&#227;&#238; &#238;&#225;&#250;&#229;&#234;&#242;&#224; &#228;&#235;&#255; &#238;&#230;&#232;&#228;&#224;&#237;&#232;&#255; &#241;&#238;&#225;&#251;&#242;&#232;&#255;
begin

   Win32Check(HandleChange <> INVALID_HANDLE_VALUE);
   
 try
//-- &#214;&#232;&#234;&#235;, &#239;&#238;&#234;&#224; &#228;&#235;&#255; &#239;&#238;&#242;&#238;&#234;&#224; &#237;&#229; &#225;&#243;&#228;&#229;&#242; &#226;&#251;&#228;&#224;&#237;&#224; &#234;&#238;&#236;&#224;&#237;&#228;&#224; Terminate
       case StrToInt(TMonDirThread(self).FK_PROVIDER_ID) of
         67..76: begin  // &#208;&#224;&#239;&#232;&#228;&#224; (&#225;&#224;&#237;&#234;&#232;)
               if send_pay = "complite" then // процедура отправки данных
                       begin // complite, &#239;&#238;&#235;&#243;&#247;&#232;&#235;&#232; &#238;&#242;&#226;&#229;&#242; &#238;&#242; &#239;&#240;&#238;&#226;&#224;&#233;&#228;&#229;&#240;&#224; (&#226;&#241;&#229; &#238;&#234;)
                               case StrTOInt(TMonDirThread(self).Error) of
                               0:      begin  // &#239;&#235;&#224;&#242;&#229;&#230; &#239;&#240;&#238;&#248;&#238;&#235; &#225;&#229;&#231; &#238;&#248;&#232;&#225;&#238;&#234;
                                       if TMonDirThread(self).Final_status = "1" then // &#238;&#242;&#226;&#229;&#242; &#238;&#228;&#237;&#238;&#231;&#237;&#224;&#247;&#237;&#251;&#233; &#231;&#224;&#239;&#232;&#241;&#251;&#226;&#224;&#229;&#236; &#242;&#240;&#224;&#237;&#231;&#224;&#234;&#246;&#232;&#254;
                                               begin
                                               TMonDirThread(self).FK_TOPUP_REQUEST_CODE:="102";
                                               end
                                               else
                                               begin  // &#237;&#243;&#230;&#237;&#238; &#239;&#229;&#240;&#229;&#239;&#240;&#238;&#226;&#229;&#240;&#255;&#242;&#252; &#241;&#242;&#224;&#242;&#243;&#241;, &#242;&#240;&#224;&#237;&#231;&#224;&#234;&#246;&#232;&#254; &#237;&#229; &#231;&#224;&#239;&#232;&#241;&#251;&#226;&#224;&#229;&#236; &#232; &#241;&#242;&#224;&#226;&#232;&#236; &#241;&#242;&#224;&#242;&#243;&#241; 106 (&#239;&#229;&#240;&#229;&#239;&#240;&#238;&#226;&#229;&#240;&#232;&#242;&#252;)
                                                       // &#242;&#224;&#234;&#230;&#229; &#231;&#224;&#237;&#238;&#241;&#232;&#236; &#238;&#241;&#237;&#238;&#226;&#237;&#251;&#229; &#239;&#229;&#240;&#229;&#236;&#229;&#237;&#237;&#251;&#229; &#226; &#242;&#224;&#225;&#235;&#232;&#246;&#243; PEYMENT (DESCRIPTION)
                                               TMonDirThread(self).FK_TOPUP_REQUEST_CODE:="106";
                                               end;
                                       end;

                               end;
                       end
                       else
                       begin  // &#239;&#240;&#238;&#232;&#231;&#238;&#248;&#235;&#224; &#238;&#248;&#232;&#225;&#234;&#224;  &#241;&#226;&#255;&#231;&#232; c &#239;&#240;&#238;&#226;&#224;&#233;&#228;&#229;&#240;&#238;&#236;

                       //fMonDirMain.lbLog.Items.Add("  &#238;&#248;&#232;&#225;&#234;&#224; &#225;&#225;&#236;&#229;&#237;&#224; &#228;&#224;&#237;&#237;&#251;&#236;&#232;   ");
                       end;
               end;

end;
 finally
  Synchronize(ThreadStop);
 // TMonDirThread(self).Terminate;
 // TMonDirThread(self).ThreadStop;     //&#209;&#238;&#238;&#225;&#249;&#224;&#229;&#236; &#238; &#231;&#224;&#226;&#229;&#240;&#248;&#229;&#237;&#232;&#232; &#239;&#238;&#242;&#238;&#234;&#224;
  //Application.ProcessMessages;
 end;
end;


 
Slym ©   (2007-08-31 04:58) [2]

ЭТО ПОЛНЫЙ ПИСЕЦ... еще и с GOTO! конструктор с 16! параметрами ааа! ущипните миня! с юзанием контролов формы... перерь понятно почему как бы вылетают (перестают работать)


 
Slym ©   (2007-08-31 05:01) [3]

Пади еще и ado пользуешь... межпоточно гыгы...


 
Slym ©   (2007-08-31 07:18) [4]

Решение - навести порядок в коде...
1. Убрать goto
2. Убрать прямое использование контролов формы (lbLog,sbMain,Application)
Логи можно PostMessage или через Synchronize
3. TOPUP_Query - тоже с контролами взаимодействует (EnableControls) и его в потоке нежелательно юзать: создавай внутри потока и пользуй
4. Потоки ограничивают объектами синхронизации: в данном случае подойдет hSem:=CreateSemaphore(nil,MaxThread,MaxThread,nil);
для ожидания WaitForSingleObject(hSem,);
для освобождения ReleaseSemaphore
5. и функция с 16 параметрами это нерулез...
можно же поток Suspend сделать присвоить параметры и  потом Resume ему сделать
или лучше Калбак функцию в поток передавать if not OnDataNeed(self) then terminate;
поток запросил, если нету терминат
6. создаваемые потоки отправляешь в свободное плавание, даже ссылки не сохраняешь...
это плохо- заведи список потоков
7. Для таких как ты придумали with
with fMonDirMain.TOPUP_Query do
begin
 FieldByName
 FieldByName
end;

эквивалентен твоему + оптимизация
fMonDirMain.TOPUP_Query.FieldByName
fMonDirMain.TOPUP_Query.FieldByName


 
Сергей М. ©   (2007-08-31 08:24) [5]


> procedure TMonDirThread.Execute;
> var
>  HandleChange: THandle;  //Handle &#241;&#238;&#231;&#228;&#224;&#226;&#224;&#229;&#236;&#238;&#227;&#238; &#238;&#225;&#250;&#229;&#234;&#242;&#224; &#228;&#235;&#255;
> &#238;&#230;&#232;&#228;&#224;&#237;&#232;&#255; &#241;&#238;&#225;&#251;&#242;&#232;&#255;
> begin
>
>    Win32Check(HandleChange <> INVALID_HANDLE_VALUE);


А это что за безобразие ?!


 
kaharin ©   (2007-08-31 12:39) [6]

Slym -->

1. Убрать goto - согласен
7. Для таких как ты придумали with - это дело привычки

4. Потоки ограничивают объектами синхронизации: в данном случае подойдет hSem:=CreateSemaphore(nil,MaxThread,MaxThread,nil);
для ожидания WaitForSingleObject(hSem,);
для освобождения ReleaseSemaphore - а по подробней плиз

Сергей М. -->

> procedure TMonDirThread.Execute;
> var
>  HandleChange: THandle;  //Handle &#241;&#238;&#231;&#228;&#224;&#226;&#224;&#229;&#236;&#238;&#227;&#238; &#238;&#225;&#250;&#229;&#234;&#242;&#224; &#228;&#235;&#255;
> &#238;&#230;&#232;&#228;&#224;&#237;&#232;&#255; &#241;&#238;&#225;&#251;&#242;&#232;&#255;
> begin
>
>    Win32Check(HandleChange <> INVALID_HANDLE_VALUE);

>А это что за безобразие ?!

Это так случайно осталось (уже убрал)


 
Сергей М. ©   (2007-08-31 12:49) [7]


> Это так случайно осталось (уже убрал)


Вот давай-ка ты сначала все свои "случайности" убери-причеши и выложи только имеющий значение и смысл хорошо отформатированный код - потом и разговор будет серъезный.


 
kaharin ©   (2007-08-31 19:02) [8]

да...
как выяснилось вся проблема заключается в TIdHTTP
он коряво работает..

то есть спотыкается вот здесь (отправка запроса)
TMonDirThread(self).TInSouse:=TMonDirThread(self).HTTP.Get(TMonDirThread(self).U RLZapros);
и ни туды и ни сюды,

соответственно у меня динамический поток вот и не заканчивается

если ли у кого мысли?

код создания
Function TMonDirThread.prepare_connection():string;
var
tmp_string:string;
begin
case StrToInt(TMonDirThread(self).FK_PROVIDER_ID) of
67..76:         begin
               TMonDirThread(self).HTTP := TIdHTTP.Create(nil);
               TMonDirThread(self).HTTP.Request.UserAgent := "Mozilla/3.0 (compatible; aviwiever)";
               TMonDirThread(self).HTTP.Host:="online.rapida.ru";
               TMonDirThread(self).HTTP.Port:=443;
               TMonDirThread(self).HTTP.Request.ContentType:="text/xml";

               TMonDirThread(self).SSL :=TIdSSLIOHandlerSocket.Create(nil);
               TMonDirThread(self).SSL.SSLOptions.CertFile:="C:\sert\rapida\cert.pem";
               TMonDirThread(self).SSL.SSLOptions.KeyFile:="C:\sert\rapida\key.pem";
               //TMonDirThread(self).SSL.OnGetPassword:= GetKeyPassword;
               TMonDirThread(self).SSL.SSLOptions.Method:=sslvSSLv23;
               TMonDirThread(self).HTTP.IOHandler:=TMonDirThread(self).SSL;
               tmp_string:= "502 041909782;500 "+ TMonDirThread(self).ACCOUNT_NUMBER +";501 "+ TMonDirThread(self).FIO +";503 "+TMonDirThread(self).CONTRACT_NUMBER;
               TMonDirThread(self).URLZapros:=www.ru.ru?Params="+tmp_string;
               if loging then LogWriteString("&#199;&#224;&#239;&#240;&#238;&#241;&#185; "+InttoStr(TMonDirThread(self).ThreadID)+"......"+TMonDirThread(self).URLZapros);
               end;

end;

Function TMonDirThread.send_pay():string;
begin
case StrToInt(TMonDirThread(self).FK_PROVIDER_ID) of
     67..76: begin
               try
                       TMonDirThread(self).prepare_connection;
                       fMonDirMain.lbLog.Items.Add(TMonDirThread(self).URLZapros);
                       try
                       TMonDirThread(self).HTTP.Connect;
                       TMonDirThread(self).TInSouse:=TMonDirThread(self).HTTP.Get(TMonDirThread(self).U RLZapros); // &#238;&#242;&#241;&#251;&#235;&#224;&#229;&#236; &#232; &#239;&#238;&#235;&#243;&#247;&#224;&#229;&#236; &#238;&#242;&#226;&#229;&#242; &#238;&#242; &#239;&#240;&#238;&#226;&#224;&#233;&#228;&#229;&#240;&#224;

                       if Length(TMonDirThread(self).TInSouse) <> 0 then // &#229;&#241;&#235;&#232; &#238;&#242;&#226;&#229;&#242; &#237;&#229; &#239;&#243;&#241;&#242;&#238;&#233; &#242;&#238; &#239;&#229;&#240;&#229;&#228;&#224;&#247;&#224; &#239;&#240;&#238;&#248;&#235;&#224; &#243;&#241;&#239;&#229;&#248;&#237;&#238; &#232; &#237;&#224;&#247;&#232;&#237;&#224;&#229;&#236; &#239;&#240;&#238;&#226;&#229;&#240;&#255;&#242;&#252; &#242;&#238; &#247;&#242;&#238; &#237;&#224;&#236; &#238;&#242;&#226;&#229;&#242;&#229;&#235; &#239;&#240;&#238;&#226;&#224;&#233;&#228;&#229;&#240;
                               begin
                               fMonDirMain.lbLog.Items.Add("2.........     "+TMonDirThread(self).TInSouse);
                               end;
                      // Parse_pay;
                       result:="complite";
                       if loging then LogWriteString("&#206;&#242;&#226;&#229;&#242;&#185; "+InttoStr(TMonDirThread(self).ThreadID)+"......"+TMonDirThread(self).TInSouse);

                       except
                       on E : Exception do
                                       begin
                                       fMonDirMain.lbLog.Items.Add(E.Message);
                                       result:="check_fatal";
                                       if loging then LogWriteString("&#206;&#248;&#232;&#225;&#234;&#224; &#238;&#242;&#226;&#229;&#242;&#224;&#185; "+InttoStr(TMonDirThread(self).ThreadID)+"......"+E.Message);
                                       end;
                       end;

               finally
               TMonDirThread(self).HTTP.Disconnect;
               if TMonDirThread(self).SSL <> nil then TMonDirThread(self).SSL.Free;
               HTTP.Free;
               end;
               end;
end;
end;


 
Slym ©   (2007-09-03 14:17) [9]

1. TMonDirThread(self) - писать больше нечего?
2. TMonDirThread(self).HTTP.Connect; - убери
3. fMonDirMain.lbLog.Items.Add - срочно убери
пока не поймешь что VCL не переваривает "левых" потоков бейся челом об клаву
4.
TMonDirThread(self).HTTP.Disconnect;
              if TMonDirThread(self).SSL <> nil then TMonDirThread(self).SSL.Free;
              HTTP.Free;

достаточно HTTP.Free;


 
Сергей М. ©   (2007-09-03 14:28) [10]


> TMonDirThread(self)


Это зачем ?


 
evvcom ©   (2007-09-03 14:31) [11]


> для освобождения ReleaseSemaphore - а по подробней плиз

А книжку умную почитать? Или тебе ее сюда выложить?
Про потоки почитай, про синхронизацию, примеры разбери, что бывает, когда нет синхронизации, а потом подумай, а заточена ли VCL под мультипоточность?



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

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

Наверх




Память: 0.55 MB
Время: 0.025 c
2-1189059357
Bast
2007-09-06 10:15
2007.09.30
---------------


5-1161675753
Sansy
2006-10-24 11:42
2007.09.30
dll при создании компоненты


2-1188993958
Странник81
2007-09-05 16:05
2007.09.30
Вывод файла на экран


15-1188844710
ArtemESC_
2007-09-03 22:38
2007.09.30
Обидели честную душу...


15-1188304203
@!!ex
2007-08-28 16:30
2007.09.30
Task Manager. Куда копать?