API-ul Win32 permite programatorului să gestioneze alocarea de timp între fire; acest lucru se aplică și aplicațiilor scrise în Delphi. Sistemul de operare programează timpul procesorului în conformitate cu prioritățile firului.
Prioritatea debitului este o valoare care constă din două componente: prioritatea firului care a generat firul și prioritatea reală a firului. Când se creează un fir, îi este atribuită o prioritate corespunzătoare priorității procesului care la generat.
La rândul lor, procesele pot avea următoarele clase de prioritate.
- Timp real;
- Normal;
- ridicat;
- Sub normal;
- Peste normal;
- Idle.
Clasa în timp real stabilește prioritatea chiar mai mult decât multe procese din sistemul de operare. Această prioritate este necesară pentru procesele care procesează fluxurile de date de mare viteză. Dacă un astfel de proces nu se termină într-un timp scurt, utilizatorul va simți că sistemul nu mai răspunde, deoarece procesarea chiar a evenimentelor mouse-ului nu va dura timpul procesorului.
Utilizarea clasei înalte se limitează la procesele care trebuie finalizate într-un timp scurt, astfel încât să nu provoace o situație proastă. Un exemplu este un proces care trimite semnale către un dispozitiv extern; iar dispozitivul se oprește dacă nu primește un semnal în timp util. Dacă aveți probleme cu performanța aplicației dvs., ar fi greșit să le rezolvați pur și simplu prin creșterea priorității sale la mare - acest proces afectează de asemenea întregul sistem de operare. Poate că în acest caz ar trebui să faceți upgrade la computer.
Cele mai multe procese sunt executate într-o clasă cu prioritate normală. Prioritatea normală înseamnă că procesul nu necesită o atenție specială din partea sistemului de operare.
Prioritățile au valori de la 0 la 31. Procesul care a generat firul poate ulterior să-și schimbe prioritatea; În această situație, programatorul are capacitatea de a controla rata de răspuns a fiecărui fir.
Prioritatea de bază a unui fir constă în două componente, dar aceasta nu înseamnă că este pur și simplu egală cu suma lor. Uită-te la valorile corespunzătoare, care sunt prezentate în Tabelul. 29.1. Pentru un fir cu prioritate proprie THREAD_PRIORITY_IDLE, prioritatea de bază va fi 1, indiferent de prioritatea procesului care a generat-o.
Și pentru clasa Normal, sunt date două priorități, fiecare cu literele B (Background) și F (Foreground). O explicație a acestui lucru este prezentată mai jos.
Pe lângă prioritatea de bază descrisă în acest tabel, planificatorul poate atribui așa-numitele priorități dinamice. Pentru procesul de clasă NORMAL_PRIORITY_CLASS atunci când trecerea din fundal în prim-plan, iar în alte cazuri prioritatea firului, care a creat fereastra de prim-plan este crescut. Acesta este modul în care funcționează toate sistemele de operare client de la Microsoft. Serverele de operare pentru servere sunt optimizate pentru a rula aplicații de fundal. Cu toate acestea, Windows NT și sisteme de operare mai târziu pe acest comutator de bază permite Modul de optimizare folosind Comutare aplicație de răspuns applet panoul de control al sistemului de operare Windows (Fig. 29.1).
Fig. 29.1. Folosind dialogul Opțiuni de performanță, puteți controla algoritmul de atribuire a priorităților
Acum, că înțelegeți prioritățile firelor, trebuie să le spuneți cum le utilizează planificatorul de sarcini pentru a aloca timpul procesorului.
Sistemul de operare are cozi diferite de fire gata pentru a rula - fiecare pentru propriul nivel de prioritate. În momentul distribuirii unui nou cuantum al timpului, acesta privește cozile - de la cea mai înaltă prioritate la cea mai mică. Un fir gata de execuție care este primul în coada de așteptare primește acest cuantum și se mută la coada coadă. Fluxul va fi executat pe întreaga durată a cuantumului, dacă nu apare unul dintre cele două evenimente:
- firul rulant sa oprit pentru a aștepta;
- A apărut un fir cu o prioritate mai mare pentru execuție.
Acum, probabil, sunteți mai clar cu privire la pericolul care rezultă din supraestimarea nejustificată a priorităților. La urma urmei, dacă există thread-uri active cu prioritate ridicată, niciun fir cu o prioritate mai mică nu va primi vreodată timpul procesorului. Această problemă poate să vă aștepte chiar și la nivelul cererii dvs. Să presupunem că atribuiți fire de calcul THREAD_PRIORITY_ABOVE_NORMAL prioritate și a fluxului care se ocupă de date introduse de utilizator, - THREAD_PRIORITY_BELOW_NORMAL. Apoi, în loc de rezultatul planificat - pentru a combina calculele cu răspunsul normal al aplicației - veți obține strict invers. Aplicația va înceta, în general, să răspundă la intrare și va fi posibilă eliminarea acesteia numai cu ajutorul facilităților sistemului de operare.
Deci, practica obișnuită pentru firele asimetrice este aceea de a atribui firului care procesează intrările la o prioritate mai mare, iar toate celelalte la un idle inferior sau chiar prioritar, dacă acest fir trebuie executat numai în timpul întreruperii sistemului.