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

Poziv threada vlastitom fumkcijom i rezultat obrade

[es] :: Pascal / Delphi / Kylix :: Poziv threada vlastitom fumkcijom i rezultat obrade

[ Pregleda: 2407 | Odgovora: 13 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

komplikator
Programer / sys. inženjering
CRO

Član broj: 29755
Poruke: 158
..140.218-dsl.net.metronet.hr.

ICQ: 13387003


+8 Profil

icon Poziv threada vlastitom fumkcijom i rezultat obrade19.11.2012. u 12:42 - pre 111 meseci
Hej!

Radio sam do sada dosta stvari sa threadovima. Nije problem sinhronizacija, znam o critical sekcijama, o suspendu, resume, execute i sve ostalo...

Mene interesira slijedeće:

Imam klasu koja je nešto obrađuje i ujedno je ta klasa i thread. Tu klasu želim nakon što je konstruiram želim pozvati s nekoliko funkcija/metoda koje imaju različite parametre i poslovna pravila, a na kraju obrade
tj. na terminate threada trebaju vratiti rezultat nekog određenog tipa (record).

Postoji li još neka ideja osim korištenja overloadanih konstruktora?

Naime, ako dodam kreiram thread u suspend modu, i nakon kreiranja mu zadam neku obradu metodom obrade (koja zapravo popuni lokalna polja i posloži proces obrade) nakon resume ne ode u execute i odradi ga nego odmah vrati rezultat (opet presliku lokalnih polja u threadu) i tek potom zavrti execute.

Znači, meni se thread treba ponašati na sitem:

Ullazni podaci : Tulaznipodaci;
Mojrezultat : TMojrezultat;

MojThread := TMojthread.Create (neki parametri);
Mojrezultat := GetMojRezultat ( ulaznipodaci);

if assigned (MojThread) then FreeandNil (MojThread); ,doduše ne bukvalno ovako.


A thread bi se trebao konstruirati s nekiparametri i ostatu u suspendu, potom bi mu podatke napunio s ulazni podaci, a on bi ušao u execute, na na terminate vratio glavnom procesu vrijednost Mojrezultat.
Osim GetMojrezultat postoji nekoliko metoda za različite tipove i s različitim tipovima vraćenog podatka.

Ima li tko ideju? Ako ne ide lakše rastavit ću sve na zasebne klase, no iz nekih razloga bolje bi mi odgovaralo da se sve vrti kao jedna klasa.





God is real unless is declared as integer.
 
Odgovor na temu

savkic
Igor Savkić

Moderator
Član broj: 92186
Poruke: 2685



+78 Profil

icon Re: Poziv threada vlastitom fumkcijom i rezultat obrade19.11.2012. u 13:25 - pre 111 meseci
> Naime, ako dodam kreiram thread u suspend modu, i nakon kreiranja mu zadam neku obradu metodom obrade (koja zapravo popuni lokalna polja i posloži proces obrade)
> nakon resume ne ode u execute i odradi ga nego odmah vrati rezultat (opet presliku lokalnih polja u threadu) i tek potom zavrti execute

Upotreba Suspend i Resume se kod threadova ne preporučuje.

> Znači, meni se thread treba ponašati na sitem:
> Ullazni podaci : Tulaznipodaci;
> Mojrezultat : TMojrezultat;
> MojThread := TMojthread.Create (neki parametri);
> Mojrezultat := GetMojRezultat ( ulaznipodaci);

Znači želiš da se poziv thread funkciji ponaša sinhrono (da se blokira glavni thread dok pomoćni ne završi obradu)?

Pogledaj www.elitesecurity.org/t357249, dat je primer kako se to može uraditi.
 
Odgovor na temu

komplikator
Programer / sys. inženjering
CRO

Član broj: 29755
Poruke: 158
..140.218-dsl.net.metronet.hr.

ICQ: 13387003


+8 Profil

icon Re: Poziv threada vlastitom fumkcijom i rezultat obrade19.11.2012. u 13:58 - pre 111 meseci
Glavni thread i dalje treba primati razne evente, mesage i sl. iscrtavati progress, biti u mogućnosti da se klikne na drugu formu ili sl. U međuvremenu se čeka povratna vrijednost, a kad se pojavi ovaj mi to signalizira i mogu raditi nešto dalje, ako se sve odulji ili sl. mogu ga i prekinuti itd...

Inače bi ga koristio po principu da mu pošaljem inicialnu vrijednost još u konstruktoru, ovaj odradi što treba i sinhronizacijom ili sl. okine neki svoj event koji je vezan na glavni thread tj. formu gdje pročitam vrijednost i vozi dalje. I to napravi različitim eventima za različite tipove rezultata.

No elegantnije bi mi bilo napraviti to kao što sam gore napisao.

O čemu se radi? radi se o fiskalizaciji u HR.
XML, digitalni potpis XML-a. dig. potpis stringa, sopa i sve ostalo radi bez problema. radio sam jednu varijantu koja komunicira datotekama po principu upit/odgovor (za stare clipper porgrame i sl.) i varijantu za noviji soft u Delphiju.

Smisao je da istodobno imam otvoreno nekoliko računa, svaki u svom tabsheetu. Na bilo koji račun mogu kliknuti na gumb ispisa tj. fiskalizacije i čekati par sekundi (tj. do nekog timeouta). Dok u međuvremenu čekam, recimo mogu se prebaciti na drugi račun i isto kliknuti paralelno i njegovu fiskalizaciju, u nekom trenutku mi ovaj prethodni račun recimo javi da je sve odradio, tj. krene na tiskanje računa, pa potom i onaj drugi... Ili se vratim na prethodni i ponovim ga, ili ako se slučajno vrti mimo svih timeouta (što je bar teoretski moguće uslijed ne znam kakve greške), mogu ga terminirati, suspendati...

Osim fiskalizacije računa radim još neke metode propisane u fiskalizaciji, i želim ih sve držati pod kapom iste klase bez polimorfizma i ostaloga, iako im se neki temeljni dijelovi klasa poklapaju i preklapaju.

Smislili su (brazilski sistem) fiskalizacije, on-line, soap-om i zato postoji moguće čekanje, neočekivani ispadi linije tijekom obrade, pucanje certifikata, i svašta nešto što se takvim online riješenjem vuče.

Recimo, trenutno imam nešto ovakovo no baš mi se i ne čini da radi u threadu i da radi kako spada:
Code:

function TFiskalProcesor.GetRacunZahtjev(const aRacunZahtjev: TRacunZahtjev): TRacunOdgovor;
begin
   FillChar(fRacunZahtjev, SizeOf(fRacunZahtjev), 0); // praznim varijablu zahtjeva
   ftipDokumenta := fdRacun;
   fRacunZahtjev := aRacunZahtjev;

   if aRacunZahtjev.Racun.BrRac.BrOznRac <> '' then

      fREQFileName := aRacunZahtjev.Racun.BrRac.OznPosPr + '-' +
                      aRacunZahtjev.Racun.BrRac.OznNapUr + '-' +
                      aRacunZahtjev.Racun.BrRac.BrOznRac
      else fREQFileName := TFiskalizacija.NewGuidAsString;

  // Resume;
   Execute;  // ovdje ide prava, potpuna validacija, obrada, potpis, slanje, obrada rezultata, praćenje grešaka i sve ostalo

   if ( fStatus = stKrajTransakcije) and (fTijekStatusa in [tsZavrseno,tsOdbaceno, tsGreska])  then
       Result := fRacunOdgovor;



Odnosno, onaj nepravilni Execute; zamijenjen sa Resume; self.WaitFor; otprilike radi posao, no čini mi se da nije to - to.

Možda te samo nisam dobro razumio, idem detaljnije proučiti onaj link. Waitfor i ostali mi nisu od pretjerane koristi...

BTW, hvala, uvijek imaš dobre savjete i odgovore.


[Ovu poruku je menjao komplikator dana 19.11.2012. u 15:28 GMT+1]
God is real unless is declared as integer.
 
Odgovor na temu

savkic
Igor Savkić

Moderator
Član broj: 92186
Poruke: 2685



+78 Profil

icon Re: Poziv threada vlastitom fumkcijom i rezultat obrade19.11.2012. u 21:29 - pre 111 meseci
> Inače bi ga koristio po principu da mu pošaljem inicialnu vrijednost još u konstruktoru, ovaj odradi što treba i sinhronizacijom ili sl. okine neki svoj event koji je vezan
> na glavni thread tj. formu gdje pročitam vrijednost i vozi dalje. I to napravi različitim eventima za različite tipove rezultata.

Koristi PostMessage, ili Event bolje je od sinhronizacije.

> Smisao je da istodobno imam otvoreno nekoliko računa, svaki u svom tabsheetu. Na bilo koji račun mogu kliknuti na gumb ispisa tj. fiskalizacije i čekati par sekundi
> (tj. do nekog timeouta). > Dok u međuvremenu čekam, recimo mogu se prebaciti na drugi račun i isto kliknuti paralelno i njegovu fiskalizaciju, u nekom trenutku mi
> ovaj prethodni račun recimo javi da je sve odradio, tj. krene na tiskanje računa, pa potom i onaj drugi... Ili se vratim na prethodni i ponovim ga,

Ne verujem da sam uređaj može fizički podržati paralelno štampanje par računa, mora jedan po jedan. Tako i ti treba da radiš. Kasir kuca 10 računa (mada ne vidim zašto bi to radio), ti po potrebi ispisuješ artikle i međuzbir na displeju za kupca (pretpostavljam da ga imate) i kada konačno kasir potvrdi šalješ taj zahtev i pokušavaš sa štampom, a ako bude grešaka prikažeš ih.

> ili ako se slučajno vrti mimo svih timeouta (što je bar teoretski moguće uslijed ne znam kakve greške), mogu ga terminirati, suspendati...

Ne, celu logiku rada i komunikacije sa uređejem stavi u zaseban thread i u njemu vodi računa o svemu (greškama, nestalo papira, ponavljanje komande, timeouti), na kraju ili odštampaš ili ne uspeš (znaš da si sve uradio da ga odštampaš), obavestiš glavni thread da nisi uspeo i da si završio. Nema potrebe da za svaki račun praviš novi thread, samo jedan koji obrađuje zahteve kako pristižu.

Code:

> // Resume;
>   Execute;  // ovdje ide prava, potpuna validacija, obrada, potpis, slanje, obrada rezultata, praćenje grešaka i sve ostalo


Nikad ti ne treba da pozivaš Execute, na osnovu ovog primera stičem utisak da ti GetRacunZahtjev pozoveš iz glavnog threada, što znači da se sve odvija u njegovom kontekstu i tu Execute nema nikakvu ulogu. Dakle, u Execute metodi (koja se automatski poziva), vrtiš se u petlji i čekaš da stigne zahtev, kada stigne, obrađuješ ga, vraćaš rezultat i nastavljaš da čekaš naredni.
 
Odgovor na temu

reiser

Član broj: 7895
Poruke: 2314



+102 Profil

icon Re: Poziv threada vlastitom fumkcijom i rezultat obrade19.11.2012. u 21:56 - pre 111 meseci
Upravo to sto savkic kaze, ti ceo posao threada (create, execute, destroy) radis unutar jedne funkcije u glavnom threadu, i dok ti cekas da ti thread zavrsi izvrsavanje blokiras glavni thread.

Ako hoces da imas vise tabsheeta gde mozes da opalis "Stampaj" dugme i da se sve to odstampa, onda moras da imas neki kontejner gde ce ti print poslovi da se cuvaju. Nisam siguran kako ide proces stampe, ako je za to zaduzen print spooler, onda je dovoljno da prilikom svakog klika na button "Stampaj" kreras thread koji ce da odradi operacije potrebne za to, prilikom klika disejblujes button da korisnik ne moze da klike na njega, a u threadu napravis evente ili message mehanizam preko kojeg ce obavestiti glavni thread o ishodu. Kada glavni thread primi callback od printer-threada, enablujes button opet.
 
Odgovor na temu

Rapaic Rajko
Bgd

Član broj: 4105
Poruke: 802
..ppoe.dyn.broadband.blic.net.



+62 Profil

icon Re: Poziv threada vlastitom fumkcijom i rezultat obrade19.11.2012. u 22:35 - pre 111 meseci
Mislim da znam sta muci pokretaca teme.

Sledi opis realne situacije na terenu. Velika kompanijska samousluzna menza/kuhinja; jedna kasa/racunar sa povezanim kvazi POS stampacem (bilo je to doba pre PDV-a :) ), mnostvo ljudi koji se guraju u redu; prilikom izlaska iz reda dobijaju racunce sa printera. Sto je upravo usko grlo, jer je stampa radjena iz main thread-a; spooler tu ne postoji, sve stoji dok se racun ne odstampa. Nervoza u menzi koja se samo moze zamisliti...
Jos ekstremniji slucaj. Restoranska aplikacija, desetak otvorenih racuna na jednom racunaru; konobari samo lete i tapkaju po touchscreen-u; svaki ima svoje stolove/otvorene racune. Moguce je i 10-ak minuta bez racuna, a desi se i 10 racuna u jednom minutu.

Koje je resenje? Za stampu - primitivan print spooler, klasica sa TStringList-om (buffer), thread-om i critical section-om. Instanci spooler-a pristupaju main thread (kroz instance klase racuna) i spooler thread koji se stalno vrti i ceka nesto za stampu. E sad, po uzoru na spooler, sve slicne radnje/funkcije treba grupisati u klase sa thread-om i buffer-om. Osmisliti nacin povratne veze/info-a za klase iz glavnog thread-a; event-i su sasvim ok.

Pije li ovo vodu?

Pozz
 
Odgovor na temu

komplikator
Programer / sys. inženjering
CRO

Član broj: 29755
Poruke: 158
...142.52-dsl.net.metronet.hr.

ICQ: 13387003


+8 Profil

icon Re: Poziv threada vlastitom fumkcijom i rezultat obrade20.11.2012. u 07:12 - pre 111 meseci
Hvala na idejama. Situacija se ipak malo razlikuje, kod nas u HR su se odlučili za softverski oblik fiskalizacije. Znači, nema posebnog uređaja, nemaš što kumunicirati, slati fiskalnom printeru ili sl. Sve ostaje isto, samo računalo povezuješ na internet, i instaliraš sof. vertifikat tj. pcks#12 certifikat. Mijenja se softver, i fiskalizacija se odvija tako da prije tiskanja računa napraviš zahtjev u obliku xml-a. digitalno ga potpišeš po x.509 i pošalješ ssl-om soap serveru porezne uprave, a on ti odgovori. Tu je još i potpisivanje tj. generiranje nekog zaštitnog koda izdavača i još neke sitnice. Kad se taj proces odvrti, tj. porezna prihvati tvoj račun, vraća ti se identifikator (JIR) ili ako ne poštuješ xml shemu ili sl. vraća ti se opis pogrešaka i tek tada to sve upišeš do kraja u bazu i tiskaš račun. Nigdje se ništa ne pamti, nema batch obrade i slanja na kraju dana. Ovi naši nam vjeruju još manje nego vama vaši, tako da traže fiskaliziranje svakog računa prije nego ga kupac i dobije. Otišli su toliko daleko da ne došuštaju ni fiskaliziranje prometa na kraju dana za npr. pokretne trgovine, nego moraju nabaviti mobilni pristup netu ili odustati od posla.

Kako je cijeli proces vrlo osjetljiv na razne sitnice i muhe, a usto je definitivno usko grlo zbog mogućih timeouta, zbog mogućih kašnjenja ili potrebe za terminiranjem procesa i "informiranja korisnika" odlučio sam se za thread. Dodatna mi je korist upravo ovo što ste spomenuli, u dijelu softvera za birtije i pekare gdje doslovno lete računi i imam otvoreno nekoliko računa istovremeno, ako jedan uleti u neko čekanje, moram moći obraditi i ispisati neki drugi račun. Ovo informiranje korisnika zvuči na prvu loptu bedasto, no kad čekate na blagajni, svaka sekunda izgleda dugačko, osobito ako ne znate što se događa i imate osjećaj da se sve zamrznulo. Thread šalje statuse obrade i što trenutno u tom trenu radi i ima li problema, postoji li neka prihvatljiva greška u obradi i sl. i kad se to stavi u neku listu i progressbarove, i još dodatno doda kontrola da se sve odgodi, prekine, ponovno pokrene

Znači, smisao je bio pozvati thread nekom funkcijom, a ona bi na kraju vratila njegov rezultat obrade, s tim da bi se on mogao pozvati s nekoliko različitih funkcija i prema njima vratiti njihove rezultate obrade.
Klasično ga znam izvesti, bilo da napravim overloaded konstruktore pa im pošaljem različite parametre obrade, a oni na kraju pošalju neki event (ili čisti win message s kojima sam iskreno manje familijaran) no tada moram pokrenuti upit tj. thread na jednom mjestu, a na nekom event handleru vezanom uz event threada gledati što će ovaj vratiti i što će se dogoditi. I tu mi je sve jasno što i kako.
Zato sam razmišljao o elegantnijem riješenju koje bise svodilo samo na funkciju koja vraća rezultat no sve skupa ispada iz koncepcije threadova. E, to ne znam izvesti :(

Nadam se da sam sad bolje pojasnio.
God is real unless is declared as integer.
 
Odgovor na temu

komplikator
Programer / sys. inženjering
CRO

Član broj: 29755
Poruke: 158
...142.52-dsl.net.metronet.hr.

ICQ: 13387003


+8 Profil

icon Re: Poziv threada vlastitom fumkcijom i rezultat obrade20.11.2012. u 12:23 - pre 111 meseci
Sve sam odradio s eventima i overloaded/overrided konstruktorima i radi mi kako i treba. Odustajem od ove varijante poziva/odgovora threadu funkcijom. Ako tko ima riješenje neka ga slobodno ponudi. Još jednom, hvala na savjetima.
God is real unless is declared as integer.
 
Odgovor na temu

Rapaic Rajko
Bgd

Član broj: 4105
Poruke: 802
..ppoe.dyn.broadband.blic.net.



+62 Profil

icon Re: Poziv threada vlastitom fumkcijom i rezultat obrade20.11.2012. u 22:51 - pre 111 meseci
Bez thread-ova? Ali onda si napravio 'sinhronu' varijantu resenja. Sto ce reci, kad ti zapne prvi racun, stace i svi iza njega...?

Situacija je slicna Firefox-u koji otvara vise sajtova istovremeno. Ako bi jedan thread/process radio sav taj posao, cim se prvi sajt zakuca, i svi naredni ce isto.

Pozz
 
Odgovor na temu

komplikator
Programer / sys. inženjering
CRO

Član broj: 29755
Poruke: 158
...141.94-dsl.net.metronet.hr.

ICQ: 13387003


+8 Profil

icon Re: Poziv threada vlastitom fumkcijom i rezultat obrade21.11.2012. u 07:26 - pre 111 meseci
Ne, napravio sam sa threadom ali na slijedeći način - napravio sam klasu koja u sebi sadrži objekt threada, u njemu ga inicializira i sl. U sebi ima i eventhandler koji se veže na event threada (koji se pak u threadu poziva sinhroniziranom funkcijom), i polja u koja punim varijable. Klasa ima i public funkciju koja učita zahtjev, pokrene konstruira i pokrene thread i čeka da joj ovaj signalizira kako je gotov ili vrati rezultat. kad vrati rezultat ta public funkcija mi vrati true i onda pročitam odgovor. Svaki novi upit je nova instanca klase. Klasa omogućuje da thread prekineš prije vremena, signalizira stanje obrade i sl. I koliko upita imaš, toliko imaš instanci kalse.

Znači otprilike polu-pseudo napisano:
Code:


     mojaklasa := TMojaklasa.create(nil, OpcePostavke);
     try
       if mojaklasa.ObradiZahtjev (mojzahtjev) = mrOk then
          nekirezultat := mojaklasa.rezultatobrade;
     finally
        freeandnil(mojaklasa);
     end;



A mojaklasa u sebi privatno stvara thread i pokreće ga, veže se na njegov event i kad joj ovaj pošalje event ili se završi kaže - ok, šalji dalje završio sam.

Nije baš nešto, no to je najbliže onomu što želim i na način koji znam. I definitivno radi u threadovima.
God is real unless is declared as integer.
 
Odgovor na temu

komplikator
Programer / sys. inženjering
CRO

Član broj: 29755
Poruke: 158
...141.72-dsl.net.metronet.hr.

ICQ: 13387003


+8 Profil

icon Re: Poziv threada vlastitom fumkcijom i rezultat obrade30.11.2012. u 07:06 - pre 111 meseci
I opet mali problemi s threadovima.

Sve funkcionira dobro, no primjetio sam da je Delphi malo mušićav u oslobađanju memorije kod threadova.
O čemu se radi?
Thread je još u konstruktoru psotavljen na FreeOnTerminate := True i on nakon što odradi execute uredno dođe do svojeg destroya. I tu mi se čudno ponaša. Uđe u inherited Destroy-eve TThread klase i sl.
i kao "oslobodi se", no ja to u alociranoj memoriji u taskmannageru baš i ne vidim. Svaki thread mi pojede nešto memorije, od 68KB do 1MB i ta se memorija vrati tek gašenjem programa.

Ovo sam primjetio bez obzira radi li se o nekoj mojoj tthread baziranoj klasi ili o najobičnijem threadu bez ikakvih obrada, sinhronizacija, eventa, čudesa... ono gola klasa sa minimumom minimuma.

Stavio sam fastmm no nije mi nešto pametno rekao.
God is real unless is declared as integer.
 
Odgovor na temu

savkic
Igor Savkić

Moderator
Član broj: 92186
Poruke: 2685



+78 Profil

icon Re: Poziv threada vlastitom fumkcijom i rezultat obrade30.11.2012. u 21:50 - pre 111 meseci
> i kao "oslobodi se", no ja to u alociranoj memoriji u taskmannageru baš i ne vidim. Svaki thread mi pojede nešto memorije, od 68KB do 1MB i ta se memorija
> vrati tek gašenjem programa.

To je normalno, kada se pravi novi thread i treba recimo 1mb memorije Delphi MemoryManager će alocirati od sistema malo veći iznos (diskusije radi 4mb), od tih 4mb će threadu dodeliti 1mb a preostala 3 ostaviti u rezervi. Ako se opet napravi novi thread, od rezervisanih 3 će uzeti 1 (dakle neće uzimati od sistema) i preostala 2 staviti u rezervu. Kada se svi threadovi oslobode, sva 4mb će ići u rezervu, znači neće se dealocirati i u sistemu. Mislim da će memory manager neke veće pakete memorije kada se vrate njemu vratiti i sistemu ali to verovatno nije ispod 10, 20 mb.
 
Odgovor na temu

komplikator
Programer / sys. inženjering
CRO

Član broj: 29755
Poruke: 158
78.134.138.*

ICQ: 13387003


+8 Profil

icon Re: Poziv threada vlastitom fumkcijom i rezultat obrade03.12.2012. u 10:55 - pre 111 meseci
Utješio si me. Da, upravo tako se ponaša. No nisam ga isporbao u krajnjim granicama, mada to nikad nije neka ekstremna količina memorije. Inače sam alergičan na curenja memorije i neoslobađanje objekata i sl. a na pomisao na nekakve zonbi procese koji ostaju sjediti negdje u memoriji i čamiti čekajući diže mi se kosa na glavi.
God is real unless is declared as integer.
 
Odgovor na temu

Daniel Mauric
Software Architect
Novi Sad

Član broj: 3279
Poruke: 30
*.adsl-a-2.sezampro.rs.



+17 Profil

icon Re: Poziv threada vlastitom fumkcijom i rezultat obrade03.12.2012. u 14:37 - pre 111 meseci
Moram priznati da nisam procitao sve poruke, ali zelim da preporucim Omni thread library.

Ima separaciju na worker i task, gde je worker izvrsni kontekst/thread a task je posao koji treba da se obavi. Naravno ima zgodane mehanizme za komunikaciju i sinhronizaciju, kao i implementacije thread pool-a i slicno.
 
Odgovor na temu

[es] :: Pascal / Delphi / Kylix :: Poziv threada vlastitom fumkcijom i rezultat obrade

[ Pregleda: 2407 | Odgovora: 13 ] > FB > Twit

Postavi temu Odgovori

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