Princip rada sa TThread-ovima

1

Princip rada sa TThread-ovima

offline
  • Pridružio: 25 Mar 2006
  • Poruke: 67
  • Gde živiš: Doboj, Republika Srpska

Postovani,
Posto pravim jednu aplikaciju koristio sam TThread za upis i pisanje podataka u bazu. tj. sve sto radim u bayi radi preko toga. Osnovni raylog zasto sam se odlucio za to je sto sam citajuci u knjizi nasao racenicu slicunu sledecoj.
Kada koristite proces za vrsenje neke operacije a ne zelite da aplikacija bude zamrznuta dok se to desava koristite tthread i onda ja odlucim da napisem tthread za pristup bazi i sve operacije koje radim sa bazom odradim preko toga. I stvarno radi u pozadini a aplikacija radi normalno ali po zavrsenom procesu pada mi glavna aplikacija nisam koristio komandu synchronize ali kada nju koristim blokira mi glavna aplikacija pa onda imam utisak da sam sve djabe radio. Molim pomoc.

Dopuna: 28 Feb 2007 9:08

e ovako ovaj kod moram da pozovem sa metodom synchronize
procedure TProces.konektuj; var   Ucitano:boolean; begin   //showmessage('Konekcija!');   Ucitano:=False;   if Stanje<>0 then     MBPInc.Destroy;   MBPInc:=TMBPInc.Create(FGlavna);   with MBPInc do   begin     while not Ucitano do     begin       try         BPKonekcija.Connected:=True;         Application.ProcessMessages;         Ucitano:=True;       except         Ucitano:=False;       end;     end;     Ucitano:=False;     while not Ucitano do     begin       try         FLoad.Label1.Caption:='Grupe!';         Application.ProcessMessages;         SQLUGrupe.Close;         //UGrupe.Prepare;         SQLUGrupe.Open;         Ucitano:=True;       except         Ucitano:=False;       end;     end;     Ucitano:=False;     while not Ucitano do     begin       try         FLoad.Label1.Caption:='Marke!';         Application.ProcessMessages;         SQLUMarke.Close;         //UMarke.Prepare;         SQLUMarke.Open;         Ucitano:=True;       except         Ucitano:=False;       end;     end;     Ucitano:=False;     while not Ucitano do     begin       try         FLoad.Label1.Caption:='Akcije!';         Application.ProcessMessages;         SQLUAkcije.Close;         //UAkcije.Prepare;         SQLUAkcije.Open;         Ucitano:=True;       except         Ucitano:=False;       end;     end;     Ucitano:=False;     while not Ucitano do     begin       try         ZTMarke.Active:=True;         ZTGrupe.Active:=True;         Ucitano:=True;       except         Ucitano:=False;       end;     end;     Ucitano:=False;     while not Ucitano do     begin       try         FLoad.Label1.Caption:='Uredjaji!';         Application.ProcessMessages;         SQLUUredjaji.Close;         //UUredjaji.Prepare;         SQLUUredjaji.ParamByName('Start').AsInteger:=Lista*15;         SQLUUredjaji.Open;         FGlavna.IPUredjaji.DataSet:=SQLUUredjaji;         FGlavna.BPSlika.DataSource:=FGlavna.IPUredjaji;         FGlavna.BPSlika.DataField:='Slika';         FGlavna.IPAkcije.DataSet:=SQLUAkcije;         FGlavna.BPSlikaA.DataSource:=FGlavna.IPAkcije;         FGlavna.BPSlikaA.DataField:='Slika';         //SQLULUredjaja.Close;         //SQLULUredjaja.Open;         Ucitano:=True;       except         Ucitano:=False;       end;     end;   end; end;

a za ostatak koda u unitu nisam koristio metod synchronize



Registruj se da bi učestvovao u diskusiji. Registrovanim korisnicima se NE prikazuju reklame unutar poruka.
offline
  • Pridružio: 04 Sep 2003
  • Poruke: 24135
  • Gde živiš: Wien

Za pocetak izbaci application.processmessages iz threada, to je visak sigurno.
Jesi li sigurno instancirao thread? Da nisi kojim slucajem radio nad samom klasom bez instanciranja?



offline
  • Pridružio: 25 Mar 2006
  • Poruke: 67
  • Gde živiš: Doboj, Republika Srpska

application.processmessage sam naknadno ubacio posto mi je aplikacija nije nastavljala sa radom.
a evo kod koji poziva thread
  Sat.Enabled:=False;   Zavrseno:=False;   Proces:=TProces.Create(True);   Proces.Lista:=Lista;   Proces.Stanje:=Stanje;   Proces.FreeOnTerminate:=True;   Proces.Resume;   while not Zavrseno do   begin     Application.ProcessMessages;   end;   Proces.Terminate;   close;
a evo metod execute od procesa
procedure TProces.Execute; begin   if (Stanje=0) or (Stanje=1) then     synchronize(konektuj)     //konektuj   else if Stanje=2 then     //synchronize(rekonektuj)     rekonektuj   else if (Stanje=3)or(Stanje=4) then     //synchronize(snimi)     snimi   else if (Stanje=5)or(Stanje=6) then     //synchronize(otvoriu)     otvoriu   else if (Stanje=7)or(Stanje=8) then     //synchronize(OtvoriA)     OtvoriA   else if (Stanje=9)or(Stanje=10) then     //synchronize(SnimiA);     SnimiA;   FLoad.Zavrseno:=True; end;

samo prvi metod ne mogu da pozovem bez synchronize ostale mogu a njegov kod sam vec napisao.

offline
  • Emil Beli
  • Pridružio: 03 Jan 2005
  • Poruke: 2990
  • Gde živiš: Beograd

@IgorMedo

Gledajuci tvoj code, vidim da nisi bas 'ortak' sa Threadovima.
Rad sa bazama pod threadom zahteva mnogo vise znanja.
Moj ti je savet da sve to prebacis na bez upotrebe threadova (single thread aplikacija), a da sa threadovima vezbas tako sto ces napraviti programce koji ce da promeni dimenzije slike, i to 4-5 odjednom.
E kad to savladas, i savladas rad sa bazama, tek onda idi na thread.

Druga stvar je da se thread na bazama ne koristi tako kako ga ti koristis.
Prvo moras da imas kompletan objekat koji nezavisno radi sa bazama. Nezavisno, u smislu da ne zavisi ni od ceg, osim od parametara za konekciju, recimo, TDatabase komponente.
Onda moras da imas thread-pool koji ce izvrshavati kompletne objekte.. ali to je vec za 3-tier baze. Za bilo sta sto nije RDBMS -> Application Server -> Thin client ZABORAVI.

offline
  • Pridružio: 25 Mar 2006
  • Poruke: 67
  • Gde živiš: Doboj, Republika Srpska

Sve to lijepo zvuci, ali kako da naucim da radim sa threadovima kada u bilo kojoj literaturi koju imam o threadovima dvije stranice.
A sad mi objasni znacenje ove redenice:
Prvo moras da imas kompletan objekat koji nezavisno radi sa bazama.
Hvala

offline
  • Emil Beli
  • Pridružio: 03 Jan 2005
  • Poruke: 2990
  • Gde živiš: Beograd

Au, to je problematicno, izgleda ... Sad


TMojaBaznaKlasaZaRadSaBazom = class(TObject)
private
...
protected
...
public
....
end;

TMojaKlasaZaCitanjePodataka = class (TMojaBaznaKlasaZaRadSaBazom)
....
....


TMojaKlasaZaManipulacijuPodataka = class (TMojaKlasaZaCitanjePodataka)
...

I ides redom...
Implementiras metode u prvu koji sluze ka konekciju, kreiranje upita itd, pa nadogradjujes klasom koja ce imati sve sto jedna Read-Only klasa treba da ima, pa onda nadogradjujes sa klasom koja moze da radi insert, update i delete...

Jbg.. ne znam sta da ti kazem.. dosta posla tu ima. Ne mogu ni da ti dam primer ovde, sve je to po pola kilometra koda.

offline
  • Pridružio: 25 Mar 2006
  • Poruke: 67
  • Gde živiš: Doboj, Republika Srpska

Hval na pojasnjenju
Nesto slicno tom radim kada pravim pravu aplikaciju ali kada pravim nesto na brzinu koristim upite i gotove komponente nemam potreb za tim, pravim aplikaciju koja upisuje sadrzaj na stranicu pami se nepise puno koda.
Ali sa threadovima radim prvi put imali negdje literatutre.

offline
  • Pridružio: 04 Sep 2003
  • Poruke: 24135
  • Gde živiš: Wien

Princip kreiranja threada si definitivno skontao.
Ima tu jos par principa koje ja postujem (isto sam rad sa threadovima ucio sam).
Prvo, u threadu koristim lokalne varijable ili klase, ne pristupam direktno onim varijablama i klasama iz glavnog threada.

Recimo, u threadu treba da koristis neki tekst koji ti se na formi nalazi u Memo komponenti. Ne pozivas iz threada citanje teksta Memo komponente vec u instanci threada napravis string varijablu i metodu za njeno punjenje (Set metodu).
Kada kreiras thread kreiras ga u suspended stanju, pa onda iz glavnog threada preko metode Set koju imas u threadu uneses ono sto imas u Memo.text, pa onda odradis resume thread kada si tako preneo sve potrebne parametre. Beli ti je gore objasnio na primeru klasa, ja na primeru varijabli. Sve u svemu, thread treba u samom sebi da moze da inicijalizuje sve ono sto mu treba za rad, pa mu pri kreiranju iskoristis suspended flag, iskopiras podatke iz instanci klasa koje imas u glavnom threadu u instance koje imas u klasi, pa onda uradis resume threada. Na kraju odradjenog posla odradis synchronize u kojem iskopiras podatke iz lokalnih instanci u one u glavnom threadu. Puno posla, ali samo tako thread moze da radi nezavisno dovoljno dugo da ti glavni thread moze raditi nesto drugo.

Drugo, ti imas previse poziva za sinhronizaciju, tako da iako si napravio thread ti i dalje drzis glavni thread "pod pritiskom", pa u glavnom threadu ipak dolazi do zamrzavanja osvezavanja forme.
Projektuj thread tako da nema puno synchronize poziva. U toku rada threada koristi synchronize samo u vidu nekog progress eventa, a tek na kraju mu odradi synchronize koji ce da prenese podatke/rezultate glavnom threadu.

offline
  • Pridružio: 25 Mar 2006
  • Poruke: 67
  • Gde živiš: Doboj, Republika Srpska

Hval mnogo

offline
  • Emil Beli
  • Pridružio: 03 Jan 2005
  • Poruke: 2990
  • Gde živiš: Beograd

@Bobby, secamo li se "onog" problema? ehehe

Elem, sve je to normalno. Tako se uci nema druge.
Osnovne greske su koriscenje globalnih varijabli, previse oslanjanja na drugi (ili main) thread, direktno prenosenje promenjivih, zvanje threada sa vise mesta itd.
To mora da se prodje.

Medjutim, najveca greska je koriscenje threadova tamo gde nema potrebe za njima. Tu 90% ljudi gresi. Treba obratiti paznju na to da li uopste thread ima smisla za dati problem.

Ko je trenutno na forumu
 

Ukupno su 1016 korisnika na forumu :: 46 registrovanih, 3 sakrivenih i 967 gosta   ::   [ Administrator ] [ Supermoderator ] [ Moderator ] :: Detaljnije

Najviše korisnika na forumu ikad bilo je 3466 - dana 01 Jun 2021 17:07

Korisnici koji su trenutno na forumu:
Korisnici trenutno na forumu: A.R.Chafee.Jr., babaroga, bladesu, BORUTUS, darios, dekan.m, Dimitrise93, djboj, DonRumataEstorski, DragoslavS, dule10savic, FOX, Georgius, hooraay, karevski, Karla, kolle.the.kid, kybonacci, Mcdado, mercedesamg, Mi lao shu, milenko crazy north, Mixelotti, mnn2, nemkea71, nenad81, Nikolaa11, ObelixSRB, Panter, pein, Pohovani_00, procesor, robertino, Sale.S, sasa87, Simon simonović, slonic_tonic, Smiljke, solic, SR-3m, Srki94, ss10, stegonosa, Vlada78, YU-UKI, 125