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

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.045 c
8-1167150764
nali
2006-12-26 19:32
2007.09.30
Как нарисовать элипс без зазубрин (как это получается через


15-1188795881
Palladin
2007-09-03 09:04
2007.09.30
Монстроидальный Unit


15-1188467188
Ricks
2007-08-30 13:46
2007.09.30
Еще одна програма на растерзание :)


15-1188909994
Denis_
2007-09-04 16:46
2007.09.30
Палец заменит кредитку?


15-1188495169
Kolan
2007-08-30 21:32
2007.09.30
Что за кодировка: &amp;laquo;РЁСЂСЌРє Третий&amp;raquo; ?





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский