Curente în delphi

În această lecție ne vom uita la posibilitatea de a dezvolta aplicatii multi-thread în Delphi. Pentru a începe, să vedem, ce avem nevoie de aceste fluxuri aceleași pe care le reprezintă.

În scopul de a pune în aplicare multitasking, sistemul de operare alocă fiecare aplicație o anumită perioadă de timp CPU pe care încearcă să se răspândească pe prioritățile stabilite. Astfel, performanța fiecărei sarcini / fir este limitat de sistemul de operare, ca parte a timpului său CPU. Pentru a efectua orice acțiune în paralel (pseudo), putem crea fire suplimentare, și se efectuează aceste acțiuni aceleași. Dacă distribuiți în mod corespunzător orice operațiuni complexe în cererea noastră, aceasta va crește în mod semnificativ performanța software-ului.

Realizare. clasa TThread

Clase în modulul în Delphi există o clasă specială TThread, conceput pentru a crea un flux. Nu uitați să conectați unitatea de clase. Luați în considerare crearea unui flux simplu. Pentru aceasta avem nevoie pentru a scrie clasa care va fi moștenită de la TThread de clasă. Pentru a face acest lucru, vom vedea tipul nostru modul.
[Cc lang = »delphi»] Tip
TMyThread = clasa (TThread) // descrie o clasă de noul nostru flux
privat

protejat
Procedura de Executare; suprascrie; // Executa metoda va fi direct corpul fluxului -
// cod care urmează să fie prelucrate în ea.
end; [/ cc]
Acum setați cursorul la descrierea noastră a metodei Execute, apăsați Ctrl + Shift + C, pentru a trece la punerea în aplicare a acestei metode. Vom vedea următorul cod:
[Cc lang = »delphi»] Procedura TMyThread.Execute;
începe

end; [/ cc]
În corpul acestei proceduri, va trebui să scrie cod care va fi procesat în fluxul nostru.
Acesta este un mod simplu putem realiza fluxul nostru. Rămâne doar pentru a face față cu faptul că poate fi utilizat. Creați un exemplu de fluxul nostru de TMyThread:
[Cc lang = »delphi»] var MyFirstThread: TMyThread;
începe
MyFirstThread: = TMyThread.Create (False);
end; [/ cc]
În cazul nostru, am trecut la constructor Create nostru parametru de curgere fals. Acest lucru înseamnă că fluxul nostru va fi lansat imediat după crearea sa. Dacă treci Adevărat, fluxul va fi lansat când îl vom apela metoda CV. Imediat după pornire, fluxul va începe să execute codul metodei Executare.
Fluxurile pot fi stabilite prioritatea lor, din care cantitatea de timp CPU va depinde de sistemul de operare care eliberează firul activ. Cu alte cuvinte, putem regla performanța debitului în raport cu celălalt. Acest lucru se face folosind proprietățile fluxului nostru de prioritate:
[Cc lang = »delphi»] MyFirstThread.Priority: = tpNormal; [/ cc]
Există șapte niveluri de prioritate pentru fluxuri:

  • tpIdle - Cel mai scăzut nivel al debitului se realizează în cadrul unui sistem de „mers în gol“.
  • tpLowest
  • tpLower
  • tpNormal
  • tpHigher
  • tpHighest
  • tpTimeCritical - Cel mai înalt nivel. o prioritate executabil fir echivalentă cu prioritatea nucleul sistemului de operare.

Nu exagera cu prioritățile 🙂 Utilizarea tpTimeCritical sau tpHighest au mai multe fire pot face computerul dvs. „cred“. Încercați să utilizați tpLower sau tpNormal.
Există, de asemenea, o proprietate FreeOnTerminate utilă, dacă ați setat la True, fluxul este distrus automat imediat ce codul de Executare metoda este finalizată.
Pentru a efectua orice operațiuni în interiorul fluxului ciclic, care este similar cu următoarele:
[Cc lang = »delphi»] Procedura TMyThread.Execute;
începe
în timp ce adevărații
începe

se încheie;
end; [/ cc]
În timp ce ciclul de curgere conținuturi vor fi procesate până în interiorul buclei nu va fi cauzată pauză, sau până când debitul este completat manual.
Ei bine, în cele din urmă, puteți distruge fluxul metoda Terminate:
[Cc lang = »delphi»] MyFirstThread.Terminate; [/ cc]
În consecință, există o metodă care returnează true, în cazul în care fluxul a fost finalizată / distruse Terminată.
Este util să se utilizeze metoda Suspend pentru a suspenda firul, iar apoi se reia fluxul de lucru va fi folosind metoda CV. Pentru a determina dacă fluxul poate fi suspendat metoda utilizată suspendate care returnează true, în cazul în care firul este suspendat.

Una dintre principalele probleme cu fire este incapacitatea de a accesa date de la două fluxuri simultan.
[Warning] probabil un tratament simultan va duce la eroare de violare a accesului. [/ Warning]
Exemplul cel mai tipic de eroare este de referință la GUI (pentru a forma componente vizuale) din noul flux. Ideea este că GUI este redat și prelucrate în mod continuu în firul principal al aplicației, care este, de asemenea, prelucrate, iar celălalt este codul principal. Deci, dacă vom merge la GUI este încă dintr-un flux, atunci există, pentru că o eroare GUI este deja utilizat de un alt fir. Una dintre cele mai comune soluție la această problemă este de a sincroniza, care acum vom discuta.
Sincronizarea vă permite să execute o metodă în firul principal al aplicației, determinându-l la acest lucru într-un alt fir.
[Atenție] Amintiți-vă! Toate tehnicile pe care le va fi numit de fluxul corpului, va fi numit și prelucrate în acest flux. Și doar pentru apelul metodei în fluxul principal, este utilizat de sincronizare. [/ Avertizare]
De exemplu, punerea în aplicare a sincronizării ChangeGUI a crea o metodă în care ne vom referi la nostru GUI, și, în consecință, să fie executat în firul principal, și a chemat de la noul nostru. De asemenea, adaugă la num nostru câmp curent numit, în cazul în care vom păstra numărul și în mod constant crește fluxul său în interiorul corpului (de exemplu).
[Cc lang = »delphi»] Tip
TMyThread = clasa (TThread) // descrie o clasă de noul nostru flux
privat

num: întreg;
protejat
Procedura ChangeGUI; // metoda, in care vom aplica pe GUI, și care vor fi tratate pe firul principal.
Procedura de Executare; suprascrie; // Executa metoda va fi direct corpul fluxului -
// cod care urmează să fie prelucrate în ea.
se încheie;

Procedura TMyThread.ChangeGUI;
începe
Form2.Label1.Caption: = IntToStr (num); // Afișează noua valoare a num
se încheie;

Procedura TMyThread.Execute;
începe
în timp ce adevărații
începe
în cazul în care num = 1000000 atunci
num: = 0;

Inc (num); // Unitate Increase num

Sincronizare (ChangeGUI); // Aceeași sincronizare! Schimbarea Label1 eticheta în fluxul principal
se încheie;
se încheie;

Procedura TForm2.FormCreate (Expeditor: TObject);
var
MyFirstThread: TMyThread;
începe
MyFirstThread: = TMyThread.Create (False); // Crearea nostru Feed
MyFirstThread.Priority: = tpLower; // Setare prioritate
se încheie;
[/ Cc]
Dupa cum se poate vedea din lista de mai sus, în scopul de a provoca un flux în metoda fluxul principal, trebuie să treacă această metodă ca parametru pentru metoda Sincronizați. Dacă apelați o metodă nu prin Synchronize, atunci eu sunt sigur că programul nu va trăi mult timp 🙂 probabil să apară unele conflicte, fie în fluxul principal sau în noul nostru, astfel încât programul termină executarea acesteia cu o eroare.
În general, fluxurile de studiu, experimentul cu ei, și eu întotdeauna ca atașarea unei surse, pe care îl puteți descărca de la acest link.