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: 5064 | Odgovora: 30 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

salvaric
Novi Sad

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



+4 Profil

icon Re: Free Thread u Lazarus-u12.12.2015. u 21:42 - pre 100 meseci
Hvala Igore na obrazloženjima problematike,

ipak se vraćam na upravljanje komponenti iz mainthread-a, eventualno neke manje stvari da obrađujem iz drugih thread-ova.

Prebacio sam proceduru u mainthread, Application.ProcessMessages joj daje malo bolji efekat unutar procedure, i radi kako treba.

Testirao sam for petljom proceduru 500 puta, fercera kako treba.

Hvala još jednom svima!
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-u13.12.2015. u 00:00 - pre 100 meseci
Nema na cemu, mislim da ti to i jeste najbolji pristup, sto ti je i savkic vec pisao.

Bukvalno, uprosceno, imas dugme "Obradi" na ciji pritisak pocinje neka duza obrada podataka koja ti "zakljuca" main (UI) formu, pa ti aplikacija deluje blokirano ("zamrznuto"). Promenis logiku da se pritiskom na dugme samo dugme disable-uje (kako ne bi moglo ponovo da se klikne), i da se pokrene poseban thread koji ce da odradi obradu - za to vreme tvoja aplikacija normalno odgovara na komande korisnika, nije zamrznuta. Po zavrsetku obrade, thread signalizira main (UI) formi (thread-u) da je obrada gotova (PostMessage, TEvent, sta god), i ti prikazes podatke (i po potrebi ponovo enable-ujes dugme).

Jedino na sta treba ovde obratiti paznju jeste da neka druga komanda ne moze da poremeti reakciju na zavrsetak thread-a - recimo ako neko u medjuvremenu izotvara neke druge forme (dok tvoj thread "obrada" jos uvek radi, jer forma vise nije zakljucana/blokirana, pa moze da se po njoj klikce), kad jednom thread zavrsi moras misliti na to sta ce se dalje desiti - ako saljes poruku koja ce za rezultat imati upisivanje neke vrednosti u npr. edit komponentu main forme, pritom je i fokusirajuci, to moze biti problem ako preko toga imas jos neke (u medjuvremenu) otvorene forme, pa tvoja edit komponenta ne moze da prihvati fokus (jer je i cela forma u pozadini, neaktivna), cak mozes dobiti i exception (npr. "cannot focus disabled window", ili tako nesto), sto sigurno nije prijatno za krajnjeg korisnika, niti pohvalno za tvoju aplikaciju.

Thread-ovi mogu biti jako zgodni, ali su u pocetku mozda malo tezi za shvatanje jer razbijaju uobicajeni "linearni" tok izvrsavanja programa, gde u svakom trenutku znas sta ce se, i kada desiti. Kod thread-ova to ne vazi, i jedino je bitno da kad se nesto desi (kad kog to bilo), ti budes spreman da na to adekvatno reagujes, bez ugrozavanja/remecenja stabilnosti programa, i njegovog trenutnog stanja - koje se verovatno promenilo od trenutka pokretanja thread-a, jer to i jeste sustina, da vise stvari moze da se izvrsava paralelno, ali je programer taj koji mora viditi racuna da to izvrsavanje bude uskladjeno, da paralelna desavanja ne uticu negativno jedno na drugo.

p.s. Eh, sad sam tek primetio da si ubacio Application.ProcessMessages(), to je vec nesto sto treba zdusno izbegavati... :/ Da, u vecini slucajeva ce mozda raditi posao, ali je malo aljkav pristup programiranju. Ne kazem, nekad treba odraditi posao u roku, uzeti novac i preziveti mesec, ali kad mogucnosti dopustaju, izbegavati.

Zasto? Zato sto isto razbija linearni/ocekivani tok programa, ali kada se to (naj)manje ocekuje. Npr, imas gorepomenuto dugme "Obrada" na koje se pokrece neko procesuiranje, i uglavnom je tad cela aplikacija "zamrznuta" dok se procesuiranje ne zavrsi - sto znaci da inace nema nikakve potrebe da disable-ujes dugme (iako je to mozda dobra praksa, ali je u ovom slucaju nepotrebno).

Medjutim, kad u toku procesuiranja pozivas Application.ProcessMessages(), ti dozvoljavas formi da u medjuvremenu odgovara na Windows poruke (pa ona vise nije "zamrznuta"), ali to ima i jedan sporedni efekat - tada ce korisnik moci ponovo da klikne na dugme "Obrada" (koje prethodno nije imalo potrebe da bude disable-ovano), pa ce se procedura za obradu pokrenuti ponovo (dok se prethodna jos nije zavrsila), sto tek moze imati neocekivane efekte.

Ovo je samo jedan banalan primer (evo ovde upravo pricaju o tome -- http://delphi.about.com/od/obj...-processmessages-dark-side.htm), mozes ih naci jos, svejedno vredi istraziti malo i na tu stranu. Ponavljam, generalno bi to trebalo izbegavati, ali kako je realan zivot obicno (bar) malo van teorije, jedino ti znas sta ti u datoj situaciju radi posao, i da li cilj opravdava sredstvo. Jedino bi dobro bilo da budes svestan da to nije najsretnije resenje.
 
Odgovor na temu

savkic
Igor Savkić

Moderator
Član broj: 92186
Poruke: 2739



+92 Profil

icon Re: Free Thread u Lazarus-u13.12.2015. u 00:27 - pre 100 meseci
Citat:
salvaric:
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?


Ni jedna VCL komponenta nije thread safe jer sam VCL nije thread safe. Da bi došao do thread safe window handla morao bi da ga sam kreiraš (zaobidješ VCL kompletno). Dakle, sve što ima veze sa UI (user interfejsom) nije thead safe.
 
Odgovor na temu

Rapaic Rajko
Bgd

Član broj: 4105
Poruke: 810
188.124.211.*



+62 Profil

icon Re: Free Thread u Lazarus-u14.12.2015. u 08:33 - pre 100 meseci
Da li se pomenuta metoda TSetTable.SetLocalTable poziva kroz Synchronize?
Ako DA, pomenuti kod bi morao da radi. Jedino bih dodao Application.ProcessMessages u petlju, i nakon izlaska iz nje. To osigurava da MainThread odradi sve pratece akcije/poruke koje idu uz to pumpanje tabele, PRE nego sto neki drugi thread kroz svoj Synchronize mehanizam pristupi istoj komponenti.

Nisam siguran kako sad radi Synchronize, ali nekad je bilo ovako: thread posalje poruku WM_SYNCHRONIZE glavnom MainThread-u, i ovaj je kroz message handler odradi. Jedno polje poruke WM_SYNCHRONIZE sadrzi pointer na threadmethod koji treba izvrsiti, i to je to. Sad je jasnije zasto treba staviti Application.ProcessMessages gore u kod.

Pozz

P.S. Ako bi i dalje pucalo, nista lakse: postoji TMonitor klasa i metode Enter i Exit.

P.P.S. I da, with() konstrukciju sto manje koristiti; ima neobjasnjivih bug-ova s ovim, video svojim ocima (nije D sto je nekad bio).
 
Odgovor na temu

salvaric
Novi Sad

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



+4 Profil

icon Re: Free Thread u Lazarus-u14.12.2015. u 09:09 - pre 100 meseci
Da, poziva se kroz Synchronize.

Bekapovao sam projekat pre promena, tako da ću proveriti dal može tako, nisam u mythread-u stavljao Application.ProcessMessages u metodu.

Usput, koristim Lazarus, i u pravu si sa tom with() konstrukcijom i kod Lazarusa, i kad sam prebacio tu proceduru u main thread morao sam da to uklonim jer je isto pravila zakucavanja, ne znam zašta, al je tako i čim sam išao direktno sve jo bilo ok.
Nikad izvini!
 
Odgovor na temu

savkic
Igor Savkić

Moderator
Član broj: 92186
Poruke: 2739



+92 Profil

icon Re: Free Thread u Lazarus-u14.12.2015. u 10:53 - pre 100 meseci
Proveri da li postoje svezije verzije DB library koji koristis za rad sa bazom, ranije su one bile nestabilne i pravile probleme kod FPCa.
 
Odgovor na temu

salvaric
Novi Sad

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



+4 Profil

icon Re: Free Thread u Lazarus-u14.12.2015. u 21:55 - pre 100 meseci
Rešen problem,

školski primer ne razmatranja celokupne situacije. MySql baza koju sam koristio je na web serveru je limitirana (5 konekcija), a zanemario sam da već imam 13 client aplikacija koje na svakih 30 sekundi osvežavaju bazu, prebacio sam je na localhost i funkcioniše savršeno, tako da je verovatno u određenom momentu bilo 5 konekcija nakon čega dođe do bug-a.

Hvala svima!
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-u15.12.2015. u 11:43 - pre 100 meseci
Procedura u main thread-u:
Code:
       for i:=0 to 20 do
                 begin
                  MyThread  := MyThread.Create(history.TAB_HISTORY,'',PConnect);
                  MyThread.Start;
                  MyThread.WaitFor;
                  history.ShowModal;
                 end; 

history je forma u kojoj prikazujem promene nad slogom date tabele u main formi, i tabela u njoj se puni iz MyThread-a.

i ovde nasteje neki sukob thread-ova, i dolazi do zakucavanja.

U koliko ne koristim WaitFor, prikaže mi se history forma kao da sam stavio "history.Show", ali ne kao ShowModal, i u koliko kliknem na main form forma ode u pozadinu a aktivira se main forma.

A kad koristim history.Show, sve radi kako treba i 1000 puta, al mi forma history nije na vrhu, tj. jeste dok ne kliknem na main formu.

Ovu proceduru sam napravio radi testa, al bi je koristio samo bez petlje.


Nikad izvini!
 
Odgovor na temu

salvaric
Novi Sad

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



+4 Profil

icon Re: Free Thread u Lazarus-u15.12.2015. u 21:07 - pre 100 meseci
Rešeno, zatvorite temu kako ne bi više mogao pisati, pozdrav!
Nikad izvini!
 
Odgovor na temu

Rapaic Rajko
Bgd

Član broj: 4105
Poruke: 810
188.124.211.*



+62 Profil

icon Re: Free Thread u Lazarus-u16.12.2015. u 07:16 - pre 100 meseci
Citat:
salvaric:
Procedura u main thread-u:
Code:
       for i:=0 to 20 do
                 begin
                  MyThread  := MyThread.Create(history.TAB_HISTORY,'',PConnect);
                  MyThread.Start;
                  MyThread.WaitFor;
                  history.ShowModal;
                 end; 

history je forma u kojoj prikazujem promene nad slogom date tabele u main formi, i tabela u njoj se puni iz MyThread-a.

i ovde nasteje neki sukob thread-ova, i dolazi do zakucavanja.

U koliko ne koristim WaitFor, prikaže mi se history forma kao da sam stavio "history.Show", ali ne kao ShowModal, i u koliko kliknem na main form forma ode u pozadinu a aktivira se main forma.

A kad koristim history.Show, sve radi kako treba i 1000 puta, al mi forma history nije na vrhu, tj. jeste dok ne kliknem na main formu.

Ovu proceduru sam napravio radi testa, al bi je koristio samo bez petlje.



Hm, pa malo je cudan test: kreiras 20 thread-ova koji svi rade nad jednom istom formom..?
A da ti forma 'ostane na vrhu' pogledaj property StayOnTop.

Pozz
 
Odgovor na temu

salvaric
Novi Sad

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



+4 Profil

icon Re: Free Thread u Lazarus-u16.12.2015. u 08:06 - pre 100 meseci
Kod mene je to malo haotičnije, pa zbog toga ne izbacujem čitav kod.

Problem se javio iz razloga što u datom thread-u pre izvršenja poziva se splash forma (loading...) i na kraju zatvrara, bez tog radi kako je i napisano gore u kodu, što sam naknadno proverio i konsatovao. Korigovao sam malo thread, prebacio sam na ručno uništenje, FreeOnTerminate sam stavio false i u proceduri posle WaitFor thread-a dodao MyThread.Free i to je rešilo problem.
Nikad izvini!
 
Odgovor na temu

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

Strane: 1 2

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

Postavi temu Odgovori

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