Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Free Thread u Lazarus-u

[es] :: Pascal / Delphi / Kylix :: Free Thread u Lazarus-u

Strane: 1 2

[ Pregleda: 5063 | Odgovora: 30 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

salvaric
Novi Sad

Član broj: 53995
Poruke: 204
*.dynamic.isp.telekom.rs.



+4 Profil

icon Free Thread u Lazarus-u11.11.2015. u 08:52 - pre 102 meseci
Pozdrav,

Nisam imao ranije iskustva sa Thread-ovima, pa me interesuje par stvari oko funkcionisanja.

Napravio sam u zasebnom fajlu Thread koji uzima podatke iz TSQLQuery-a i smešta ih u lokalnu TCombox, i nakon izvršenja uz proceduru Synchronize prenosi podatke u TComboBox na određenoj formi.

Code:
unit ThreadS;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, sqldb, db,StdCtrls,Forms,Controls;

  type
    {TGetComboItems}
    TGetComboItems = class(TThread)
        public
          IsFinish : Boolean;
          constructor Create(sSQL,sField,sFieldID: String;
                             ComboBox:TComboBox; sIndex: Integer);
          destructor Destroy; override;
        protected
          S: String;
          tQry: TSQLQuery;
          tSQL: String;
          tCombo,Combo: TComboBox;
          tField: String;
          tFieldID: String;
          tIndex: Integer;
          procedure Execute; override;
          procedure AddToCombo;
          procedure ShowStatus;
          procedure SetCursorWait;
          procedure SetCursorDefault;
    end;

implementation

uses modul1,glava1s;

{ TGetComboItem }

constructor TGetComboItems.Create(sSQL, sField, sFieldID: String;
                                  ComboBox: TComboBox; sIndex: Integer);
begin
     FreeOnTerminate:=true;
     tQry := TSQLQuery.Create(nil);
     tQry.DataBase    := modul.konekcija;
     tQry.Transaction := modul.Transakcije;
     tQry.SQL.Clear;
     tQry.SQL.Add(sSQL);
     tQry.Open;
     tField:=sField;
     tFieldID:=sFieldID;
     tIndex:=sIndex;
     tCombo:=ComboBox;
     tCombo.Clear;
     tCombo.Enabled:=false;
     Combo:=TComboBox.Create(nil);
     IsFinish:=false;
     inherited Create(false);
end;

destructor TGetComboItems.Destroy;
begin
  tQry.Free;
  Combo.Free;
  Synchronize(@SetCursorDefault);
  inherited Destroy;
end;

procedure TGetComboItems.Execute;
begin
   if not Terminated then
    begin
     Synchronize(@SetCursorWait);
     s:='Učitavanje podataka je u toku...';
     Synchronize(@ShowStatus);
     with tQry do
      Begin
        while not eof do
          begin
            if (not IsFinish) then
              begin
                Combo.Items.AddObject(FieldByName(tField).AsString
                                     ,TObject(FieldByName(tFieldID).AsInteger));
                Synchronize(@ShowStatus);
                Next;
              end
            else
               Last;
          end;
       Close;
      end;
     IsFinish:=true;
     s:='Učitavanje podataka je izvršeno.';
     Synchronize(@ShowStatus);
     Synchronize(@AddToCombo);
    end;
end;

procedure TGetComboItems.AddToCombo;
begin
     tCombo.Items:=Combo.Items;
     tCombo.ItemIndex:=tCombo.Items.IndexOfObject(TObject(tIndex));
     tCombo.Enabled:=true;
end;

procedure TGetComboItems.ShowStatus;
begin
    Form1.Status.SimpleText:=s;
end;

procedure TGetComboItems.SetCursorWait;
begin
  Screen.Cursor:=crSQLWait;
end;

procedure TGetComboItems.SetCursorDefault;
begin
  Screen.Cursor:=crDefault;
end;

end.



Thread pozivam na sledeći način:

Code:

procedure TForm1.firma_izmClick(Sender: TObject);
var
    sFIRMA: PFirma;
    GetMesta : TGetComboItems;
begin

          // Učitavanje gradova i tekućih računa u ComboBox i indeksiranje
          GetMesta:=TGetComboItems.Create('select * from tab_mesta','mesto','id', firma_mesto, sFIRMA^.ID_MESTA);
          GetMesta.Start;
          ....
end;    


1. Interesuje me, da li je potrebno i na koji način se vrši oslobađanje memorije od Thread-a, ili se on sam uništi nakon izvršenja, pošto sam pokušavao da pozovem FreeAndNil(GetMesta) nakon izvršenja al izbaci grešku.

Iz Thread-om punim Combo jer sam želeo da se prvo otvori forma i dozvole korekcije ostalih podataka dok se i combo ne učita, jer koristim MySql sa net servera pa se podaci malo sporije učitavaju, čisto da se ne gubi vreme na učitavanje.

2. Da li je potrebno osloboditi Objekte iz ComboBox-a posle korišćenja, il je dovoljno ComboBox.Clear, pošto je objekat tipa INTEGER, ne dozvoljava mi da izvršim Object.Free nad bilo kojim slogom.

3. I da li je OK način na koji sam to rešio.


Nikad izvini!
 
Odgovor na temu

savkic
Igor Savkić

Moderator
Član broj: 92186
Poruke: 2739



+92 Profil

icon Re: Free Thread u Lazarus-u11.11.2015. u 10:47 - pre 102 meseci
> 1. Interesuje me, da li je potrebno i na koji način se vrši oslobađanje memorije od Thread-a, ili se on sam
> uništi nakon izvršenja, pošto sam pokušavao da pozovem FreeAndNil(GetMesta) nakon izvršenja al izbaci grešku.

Ako je setovan FreeOnTerminate onda i ne moras da unistavas thread ako nije onda moras (kao i svaki drugi objekat)

> Iz Thread-om punim Combo jer sam želeo da se prvo otvori forma i dozvole korekcije ostalih
> podataka dok se i combo ne učita, jer koristim MySql sa net servera pa se podaci malo sporije učitavaju,
> čisto da se ne gubi vreme na učitavanje.

Bilo koja vizuelna kontrola je vezana za glavni thread, nikako je ne smes koristiti direktno iz pomocnog threada.
Alociraj obican TStringList i u njega ubaci vrednosti koje zelis.

> 2. Da li je potrebno osloboditi Objekte iz ComboBox-a posle korišćenja, il je dovoljno ComboBox.Clear,
> pošto je objekat tipa INTEGER, ne dozvoljava mi da izvršim Object.Free nad bilo kojim slogom.

Sam si odgovorio, kako integer vrednosti nisu klase (objekti) već prosti tipovi nema potrebe da bilo šta radiš osim da isprazniš ili uništiš string listu koja ih je sadržala.

> 3. I da li je OK način na koji sam to rešio.

Moraš proveriti i da li su db komponente thread safe ili da li prave posebnu konekciju ka bazi, ako ne onda ni njih ne smeš koristiti u pomoćnom threadu na taj način. Generalno, na dobrom si putu ali imaš prostora da to bolje izvedeš i središ klasu.
 
Odgovor na temu

salvaric
Novi Sad

Član broj: 53995
Poruke: 204
*.dynamic.sbb.rs.



+4 Profil

icon Re: Free Thread u Lazarus-u11.11.2015. u 17:04 - pre 101 meseci
Kreirao sam u samom Thread-u Connection i Transaction komponente, podatke iz Query-a sam prebacio da idu u TStringList, i nakon završetka Synchronize procedurom ubacim u ComboBox, povezao sam i sve lepo radi.

Jedini problem kojo je sad nastao jeste usporeno zatvaranje programa, 3-4 sekunde nakon klika na X, samo u koliko se koristi taj thread, u koliko ne program se redovno zatvara, ne mogu da prokljuvim u čenu je caka.

Sve komponente koje se kreiraju unutar thread klase sam stavio da se oslobađaju, u proceduri Destroy.
Nikad izvini!
 
Odgovor na temu

salvaric
Novi Sad

Član broj: 53995
Poruke: 204
*.dynamic.sbb.rs.



+4 Profil

icon Re: Free Thread u Lazarus-u11.11.2015. u 20:42 - pre 101 meseci
Code:

unit ThreadS;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, sqldb,mysql55conn,StdCtrls,Forms,Controls;

  type
    {TGetComboItems}
    TGetComboItems = class(TThread)
        private
          S: String;
          tCombo: TComboBox;
          StrList: TStringList;
          tField: String;
          tFieldID: String;
          tSQL: String;
          tIndex: Integer;
          tQ : TSQLQuery;
          tConn : TMySQL55Connection;
          tTrans : TSQLTransaction;
          procedure SetEnable;
          procedure SetDisable;
          procedure PropertyQuery;
        public
          IsFinish : Boolean;
          constructor Create(sSQL,sField,sFieldID: String;
                             ComboBox: TComboBox; sIndex: Integer);
          destructor Destroy; override;
        protected
          procedure Execute; override;
          procedure AddToCombo;
          procedure ShowStatus;
          procedure SetCursorWait;
          procedure SetCursorDefault;
    end;

implementation

uses glava1s;

{ TGetComboItem }

procedure TGetComboItems.SetEnable;
begin
     tCombo.Enabled:=true;
end;

procedure TGetComboItems.SetDisable;
begin
     tCombo.Enabled:=false;
end;

procedure TGetComboItems.PropertyQuery;
begin
  // kreiranje konekcije
     tConn := TMySQL55Connection.Create(nil);
     tConn.Hostname := 'localhost';
     tConn.DatabaseName := 'baza';
     tConn.UserName := 'root';
     tConn.Password := 'root';
     tConn.CharSet:='latin1';
  // kreiranje transakcije
     tTrans := TSQLTransaction.Create(Nil);
     tTrans.Database := tConn;
  // kreiranje Query-a
     tQ := TSQLQuery.Create(nil);
     tQ.DataBase    := tConn;
     tQ.Transaction := tTrans;

     tConn.Transaction := tTrans;
  // Otvaranje konekcije i tabele
     tConn.Connected:=true;
     tQ.SQL.Add(tSQL);
end;


constructor TGetComboItems.Create(sSQL, sField, sFieldID: String;
                                  ComboBox: TComboBox; sIndex: Integer);
begin
     FreeOnTerminate:=true;
     StrList := TStringList.Create;
     tField  := sField;
     tFieldID:= sFieldID;
     tIndex  := sIndex;
     tCombo  := ComboBox;
     tSQL    := sSQL;
     IsFinish:= false;
     inherited Create(true);
end;

destructor TGetComboItems.Destroy;
begin
     FreeAndNil(StrList);
     tConn.Connected:=false;
     FreeAndNil(tConn);
     FreeAndNil(tQ);
     FreeAndNil(tTrans);
     inherited Destroy;
end;

procedure TGetComboItems.Execute;
begin
   if not Terminated then
    begin
     Synchronize(@SetDisable);
     Synchronize(@SetCursorWait);
     s:='Učitavanje podataka je u toku...';
     Synchronize(@ShowStatus);
     PropertyQuery;
     with tQ do
      Begin
        Open;
        while not eof do
          begin
            if (not IsFinish) then
              begin
                StrList.AddObject(FieldByName(tField).AsString
                                     ,TObject(FieldByName(tFieldID).AsInteger));
             //   Synchronize(@ShowStatus);
                Next;
              end
            else
               Last;
          end;
         close;
         tConn.Connected:=false;
      end;
     IsFinish:=true;
     s:='Učitavanje podataka je izvršeno.';
     Synchronize(@ShowStatus);
     Synchronize(@AddToCombo);
     Synchronize(@SetCursorDefault);
     Synchronize(@SetEnable);
    end;
end;

procedure TGetComboItems.AddToCombo;
begin
     tCombo.Clear;
     tCombo.Items.AddStrings(StrList);
     tCombo.ItemIndex:=tCombo.Items.IndexOfObject(TObject(tIndex));
     tCombo.Enabled:=true;
end;

procedure TGetComboItems.ShowStatus;
begin
     Form1.Status.SimpleText:=s;
end;

procedure TGetComboItems.SetCursorWait;
begin
     Screen.Cursor:=crSQLWait;
end;

procedure TGetComboItems.SetCursorDefault;
begin
     Screen.Cursor:=crDefault;
end;

end.

Nikad izvini!
 
Odgovor na temu

salvaric
Novi Sad

Član broj: 53995
Poruke: 204
*.dynamic.sbb.rs.



+4 Profil

icon Re: Free Thread u Lazarus-u11.11.2015. u 20:50 - pre 101 meseci
Sve lepo radi, ne prijavljuje nikakvu grešku, sem što se forma zamrzme par sekundi prilikom gašenja.
Nikad izvini!
 
Odgovor na temu

captPicard
programer
more i planine

Član broj: 216084
Poruke: 1119



+19 Profil

icon Re: Free Thread u Lazarus-u11.11.2015. u 22:21 - pre 101 meseci
Pokreni 20ak puta za redom i prati zauzeće memorije pa ćeš vidjeti da li oslobađa ili ne.
F
 
Odgovor na temu

savkic
Igor Savkić

Moderator
Član broj: 92186
Poruke: 2739



+92 Profil

icon Re: Free Thread u Lazarus-u11.11.2015. u 22:24 - pre 101 meseci
> Jedini problem kojo je sad nastao jeste usporeno zatvaranje programa, 3-4 sekunde nakon klika na X, samo u koliko se koristi taj thread, u koliko ne
> program se redovno zatvara, ne mogu da prokljuvim u čenu je caka.

Da li thread radi u tom trenutku (uzima podatke iz baze)? Ako da onda u unutrasnju petlju za db stavi i not Terminated uslov a iz glavnog threada pozovi Terminate u OnClose eventu.

 
Odgovor na temu

salvaric
Novi Sad

Član broj: 53995
Poruke: 204
*.dynamic.sbb.rs.



+4 Profil

icon Re: Free Thread u Lazarus-u11.11.2015. u 22:47 - pre 101 meseci
Memorija se oslobađa, pratio sam. Pokrenuo sam alatku Thread (View->Debug Windows->Threads), u njoj se prikažu svi thread-ovi koji su aktivni u aplikaciji, prikaže se i ovaj u trenutku kad se izvršava i kad se izvrši nestane, što znači da je završen. Proveravao sam u Destroy proceduri, posle FreeAndNil(tConn) sa Assigned(tConn) i tako svaku komponentu koja se oslobađa i nijedna ne postoji nakon oslobađanja.
Nikad izvini!
 
Odgovor na temu

Rapaic Rajko
Bgd

Član broj: 4105
Poruke: 810
188.124.211.*



+62 Profil

icon Re: Free Thread u Lazarus-u12.11.2015. u 08:16 - pre 101 meseci
Ako sam dobro shvatio, ti osim konekcije u thread-u imas i konekciju u aplikaciji (u mainthread-u)?

Malo sam proguglao, vezano za taj scenario. Ako sam dobro shvatio pricu, to sto kod tebe radi bez problema je cist sticaj okolnosti.
Mozda nema veze s tvojim slucajem, ali ipak pogledaj: http://forum.lazarus.freepascal.org/index.php?topic=27379.0 .
Javi jel sta pomoglo.

Pozz
 
Odgovor na temu

salvaric
Novi Sad

Član broj: 53995
Poruke: 204
*.dynamic.isp.telekom.rs.



+4 Profil

icon Re: Free Thread u Lazarus-u12.11.2015. u 10:29 - pre 101 meseci
Hvala Rajko,

dodao sam na glavnu formu SQLDBLibraryLoader1 komponentu i aktivirao je nakon startovanja programa i rešila je problem, nema pauze pri gašenju.

Net je čudo, svaka čast!
Nikad izvini!
 
Odgovor na temu

salvaric
Novi Sad

Član broj: 53995
Poruke: 204
*.dynamic.isp.telekom.rs.



+4 Profil

icon Re: Free Thread u Lazarus-u12.11.2015. u 11:10 - pre 101 meseci
Dal neko ima ideju kako da iz Thread-a da pozovem proceduru sa parametrima u glavnom thread-u?

Pošto Savkić kaže da izbegavam pozivanje i podešavanje vizuelnih komponenti iz Thread-a, nisam siguran da se to može izbeći u mom slučaju. Ovaj Thread sam zamislio da bude univerzalan za sve forme u projektu, a pozivam ga iz glvnog thread-a, pre pokretanja bilo koje forme, čak i u nekim delovima glavne forme se primenjuje. Dodatni problem jeste što se u određenoj proceduri poziva više puta na izvršenje u isom momentu, tipa na formi koja ima više ComboBox-ova koje treba napuniti i staviti Enable na false dok se ne učita.

Pokušao sam u glavnom thread-u da deklarišem promenjive i proceduru u "public", koju bi mogao pozavti iz mog Thread-a i menjati sa Synchronize(@Form1.SetComboBox), ali će doći do sukoba promenjive u koliko se budu izvršavala 2-3 thread-a u isto vreme.

Ili možda ideju kako da prenesem TStringList iz thread-a u glavni thread i da se učita u combo nakon završetka thread-a?

Nadam se da sam napisao šta sam mislio a da je to i razumljivo i drugima.



[Ovu poruku je menjao salvaric dana 12.11.2015. u 12:21 GMT+1]
Nikad izvini!
 
Odgovor na temu

savkic
Igor Savkić

Moderator
Član broj: 92186
Poruke: 2739



+92 Profil

icon Re: Free Thread u Lazarus-u12.11.2015. u 22:18 - pre 101 meseci
> Dal neko ima ideju kako da iz Thread-a da pozovem proceduru sa parametrima u glavnom thread-u?

Možeš preko Synchronize, ima i drugih (boljih) načiuna ali je ovo najlakši.

> Pošto Savkić kaže da izbegavam pozivanje i podešavanje vizuelnih komponenti iz Thread-a, nisam siguran da se to može izbeći u mom slučaju.

Synchronize se izvršava u kontekstu glavnog threada tako da si bezbedan.

> Ovaj Thread sam zamislio da bude univerzalan za sve forme u projektu, a pozivam ga iz glvnog thread-a, pre pokretanja bilo koje forme, čak i
> u nekim delovima glavne forme se primenjuje. Dodatni problem jeste što se u određenoj proceduri poziva više puta na izvršenje u isom momentu, tipa na
> formi koja ima više ComboBox-ova koje treba napuniti i staviti Enable na false dok se ne učita.

Važna stvar, nemoj thread posmatrati kao upravljački blok (to je uvek main thread) već kao običan worker deo, svrha threada je da izvrši neki zadatak u pozadini, kada završi može poslati neku notifikaciju pozivaocu (glavnom threadu), PostMessage je zgodan mehanizam ali takodje i TEvent. Glavni thear u međuvremenu radi svoj posao i kada stigne obaveštenje o završetku posla, obradi to što je završeno.

> Pokušao sam u glavnom thread-u da deklarišem promenjive i proceduru u "public", koju bi mogao pozavti iz mog
> Thread-a i menjati sa Synchronize(@Form1.SetComboBox), ali će doći do sukoba promenjive u koliko se budu
> izvršavala 2-3 thread-a u isto vreme.

U datom trenutklu samo jedan thread (glavni) može izvršavati Synchronize metodu, svi ostali čekaju na red.

> Ili možda ideju kako da prenesem TStringList iz thread-a u glavni thread i da se učita u combo nakon završetka thread-a?

Pošto je sve to u istom procesu, prosto pošalješ referencu na temprorary TStrings preko PostMessage, glavni thread uradi šta treba i oslobodi memoriju a pomoćni thread pravi novu kad mu treba.



 
Odgovor na temu

salvaric
Novi Sad

Član broj: 53995
Poruke: 204
*.dynamic.sbb.rs.



+4 Profil

icon Re: Free Thread u Lazarus-u11.12.2015. u 21:29 - pre 100 meseci
Naišao sam na problem sa više Synchronize procedura u Execute thread-a,

thread se nekoliko puta izvrši kako treba (nekad 10 nekad 20 puta), malo sam ga forsirao da proverim da ne dođe do problema, kad eto, bolje da nisam, šalim se.

U execute pozivam nekoliko Synchronize procedura koje izvršavaju različite operacije, npr.
1. otvaranje slash forme
2. upis u statusbar teksta nakon svake promene
3. kreiranje i otvaranje Query tabele i konekcije
4. zatvaranje slash forme
...

Negde sam na netu pronašao da je preporučeno samo jedno pozivanje Synchronize procedure unutar execute thread-a.

Pretpostavljam da dođe do zakucavanja thread-ova zbog tih multi procedura koje se sihhronizuju u isto vreme.

Nisam mogao naći neki wait te Synchronize procedure, kako bi sačekao da se izvrši pa tek onda da se nastave naredne.

Čak sam razmišljao da napravim zasebne thread-ove koji će te operacije obavljati, i u execute ih pozovem i sačekam izvršenje, mislim da je to i jedino rešenje.
Nikad izvini!
 
Odgovor na temu

savkic
Igor Savkić

Moderator
Član broj: 92186
Poruke: 2739



+92 Profil

icon Re: Free Thread u Lazarus-u12.12.2015. u 09:23 - pre 100 meseci
Synchronize se izvrsava u kontekstu glavnog threada, nemoguće je da se dve Synchronize metode izvršavaju istovremeno.

U svakom slučaju to što ti radiš ne treba raditi, glavna forma tj. glavni thred je upravljač programa, delegira i zadaje radne naloge a izvršioci (thredovi) ih rade i obaveštavaju o završetku zadatka (uspešno, neka greška i slično), glavna forma dalje odlučuje šta će raditi sa tim obaveštenjem (ignorisati, prikazati nešto u statusbaru, otvoriti/zatvoriti splash formu i slično). Dakle, nemoj ništa raditi sa UI iz threada, uradi šta se traži i obavesti naručioca o tome.
Moj ti je savet da zaboraviš na Synchronize i nikad ga ne koristiš i imaćeš mnogo brži program i manje problema u radu (mada je kod tebe nešto drugo problem).
 
Odgovor na temu

salvaric
Novi Sad

Član broj: 53995
Poruke: 204
*.dynamic.isp.telekom.rs.



+4 Profil

icon Re: Free Thread u Lazarus-u12.12.2015. u 13:20 - pre 100 meseci
U pravu si Savkiću, nije u tome problem.

Jedna procedura je punila TVirtualStringTree tabelu iz Query-a, i u njoj je problem pretpostavljam.

Code:

type
  { TCusField }

  TCusField = record
     Index    : Integer;
     Value    : variant;
     FieldName: String;
  end;  
...
type
  PData = ^TData;
  TData = object  
     Field      : array of TCusField;
     RecNo      : Integer;
     inicialize : Boolean;
     public
       function ValueOfFiledName(sName: String): variant;
       function IndexOfName(sName: String): integer;
       procedure SetValue(sName: String; Value: variant);
       procedure SetIndexValue(i: Integer; Value: variant);

  end; 
...
procedure TSetTable.SetLocalTable;
var
  Data      : PData;
  Node      : PVirtualNode;
  CustField : TCusField;
  i         : Integer;
begin
      with TVirtualStringTree(fSender) do
         begin
            BeginUpdate;
            Clear;

            RootNodeCount := tQ.RecordCount;
            NodeDataSize  := SizeOf(TCusField);   // <  mislim da je ovde negde problem
            Node          := GetFirst;

            while not tQ.EOF do
              begin
                Data := GetNodeData(Node);
                SetLength(Data^.Field,tQ.FieldCount);
                Data^.RecNo := tQ.RecNo;
                for i := 0 to High(Data^.Field) do
                  begin
                     CustField.Value     := tQ.Fields[i].Value;
                     CustField.FieldName := tQ.Fields[i].FieldName;
                     CustField.Index     := i;
                     Data^.Field[i]      := CustField;
                  end;
                Data^.inicialize    := true;
               Node:= GetNext(Node);
               end;
            end;
            EndUpdate;
         end;
end; 


Ne mogu da nahvatam gde ga zakuca, ne pokazuje nikakvu grešku, samo se zamrzne. U thread-ovima vidim da su dva pokrenuta i čekaju u trenutku zamrzavanja i ništa više, dok u momentima kad prolazi pokrene se jedan i uništi nakon izvršenja.

Milslim da je nastaje problem oko tog NodeDataSize, al mi nije jasno kako nekad hoće 20 puta a nekad se zakuca na 5.

Nikad izvini!
Prikačeni fajlovi
 
Odgovor na temu

salvaric
Novi Sad

Član broj: 53995
Poruke: 204
*.dynamic.sbb.rs.



+4 Profil

icon Re: Free Thread u Lazarus-u12.12.2015. u 17:18 - pre 100 meseci
Verovali ili ne u ovoj liniji je problem :
Code:
with TVirtualStringTree(fSender) do
zašto, kako ne znam. fSender je TObject od TVirtualStringTree koji prosleđujem prilikom kreiranja thread-a.
Nikad izvini!
 
Odgovor na temu

((BugA))
Igor Djordjevic
Bor, Srbija

Član broj: 29241
Poruke: 196
*.dynamic.sbb.rs.

ICQ: 66516695
Sajt: www.MalamutKlub.com


+17 Profil

icon Re: Free Thread u Lazarus-u12.12.2015. u 17:37 - pre 100 meseci
Je l` ovaj poslednji kod ima veze sa onim sto si postavljao u prethodnim porukama? Da se ne udubljujem sad u sve, ako nema potrebe. Ako ne, onda je vrlo nezahvalno bilo sta komentarisati iz delova koda, pogotovo kada je rec o thread-ovima. Ako si ceo kod vec postavio, onda da gledam ispocetka :)

Drugo, vidim da koristis pokazivace - jesu li podaci kojima pristupas "thread-safe", tj. ne moze da se desi da vise thread-ova odjednom drlja po njima (pise/brise)?

A to sto jednom hoce 20 puta, a jednom zakuca posle 5-og, to je lepota mutli-threading programiranja ;) Salu na stranu, koncept je vrlo prost, kad ga jednom sazvaces, ali se eventualne greske obicno tesko otkrivaju, upravo sto nemas potpunu kontrolu nad time koji se deo koda kad izvrsava, i kada ce se koji thread-ovi "nesrecno" preklopiti. Uglavnom, najbolje testiranje je kad najvise opteretis svoju logiku (sto vise thread-ova), tada se greske najlakse pojave.

E sad, kako ces da ih debug-ujes, to zavisi... Recimo, madExcept je dobar (besplatan za nekomercijalnu upotrebu), ima mogucnost da baci exception kad se aplikacija zakuca, a i daje iscrpan (i prilicno vrlo precizan) call stack, pa lako vidis koji thread gde stoji, pomazuci da odgonetnes i zasto stoji.
 
Odgovor na temu

salvaric
Novi Sad

Član broj: 53995
Poruke: 204
*.dynamic.sbb.rs.



+4 Profil

icon Re: Free Thread u Lazarus-u12.12.2015. u 17:49 - pre 100 meseci
Ima veze, u pitanju je isti program i problem.
Nikad izvini!
 
Odgovor na temu

salvaric
Novi Sad

Član broj: 53995
Poruke: 204
*.dynamic.sbb.rs.



+4 Profil

icon Re: Free Thread u Lazarus-u12.12.2015. u 17:56 - pre 100 meseci
Malo glupoo pitanje, al šta mogu, pošto nemam nikakva iskusta sa thread-ovima, i priliično sam samouk, kako da proverim dal je TVirtualStringTree "thread-safe" komponenta?
Nikad izvini!
 
Odgovor na temu

((BugA))
Igor Djordjevic
Bor, Srbija

Član broj: 29241
Poruke: 196
*.dynamic.sbb.rs.

ICQ: 66516695
Sajt: www.MalamutKlub.com


+17 Profil

icon Re: Free Thread u Lazarus-u12.12.2015. u 20:25 - pre 100 meseci
Nazalost, "thread-safe" je takodje koncept koji se mora postovati, nije osobina koja se tek tako moze proveriti, i obicno je najveca prepreka/problem kod rada sa thread-ovima. I nije glupo pitanje.

Sustina "thread-safe" podataka je da ne dozvolis da nekoj promenljivoj moze pristupati vise thread-ova odjednom - ako ce svi samo da citaju iz nje (read), to i nije problem, ali ako ce makar jedan da je menja (write) na bilo koji nacin, e onda:

(1) U trenutku dok je jedan thread menja nijedan drugi ne sme da cita iz nje - mada i tu postoji izuzetak, kada se radi o tipovima koje procesor cita/pise u jednom "cugu", pa onda je to samo po sebi "thread-safe", najbolji primer je obicno Boolean tip, neke vrste integer-a, itd. U suprotnom, moze doci do neocekivanih rezultata, npr. da thread procita polovicno promenjenu vrednost.
(2) Ako je jedan thread menjao promenljivu, drugi mora da bude spreman na to - npr. kad jedan pozove Free() na objektu, drugi vise ne sme da pristupa tom objektu (ili vec mora da bude spreman da on ne postoji, pa da dalje radi sta treba u tom slucaju).

Zapravo, "thread-safe" i nije osobina podatka (kopomonente, cega god), vec nacina pristupa/rada sa istim. Da bi odredjeni podatak (ili struktura, objekat) bio "thread-safe", programer mora da ispostuje odredjene principe/pravila prilikom pristupa i rada sa tim podacima, najcesce kroz odredjene sisteme sinhronizacije - critical section, semaphore, mutex, itd.

I kada imas (do tada) "thread-safe" pristup podacima, dovoljno je da negde uradis nesto nepromisljeno, pa da to pocne da pravi problem. "Thread-safe" je nesto sto se mora postovati sve vreme, uvek.

Oblast je podugacka da bih ti je ovde prepricavao (a i nisam trenutno bas dobar sa vremenom), najbolje ce biti da sam malo istrazis na tu temu, pa da eventualno pitas ako negde zapnes. U medjuvremenu, videcu da pogledam kod koji si postavio do sad, pa da ti eventualno ukazem na neke propuste, ukoliko ih ima, a uocim ih.

U svakom slucaju, multi-threading je jedan od tezih koncepata u programiranju, najvise zbog stalne potrebe za sinhronizacijom i poteskocama kod testiranja, da se otkriveni bug ponovi/debug-uje.
 
Odgovor na temu

[es] :: Pascal / Delphi / Kylix :: Free Thread u Lazarus-u

Strane: 1 2

[ Pregleda: 5063 | Odgovora: 30 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.