O introducere în Threading în VB.NET

Pentru a înțelege filetarea în VB.NET, vă ajută să înțelegeți câteva dintre conceptele de bază. Primul lucru este că filetarea este ceva care se întâmplă deoarece sistemul de operare îl acceptă. Microsoft Windows este un sistem de operare pre-vacant de operare multitasking. O parte din Windows a numit task planuler coletează timpul procesorului la toate programele care rulează. Aceste mici bucăți de timp ale procesorului se numesc felii de timp. Programele nu sunt responsabile de cât timp obține procesorul, programatorul de sarcini este. Deoarece aceste tranșe de timp sunt atât de mici, vă faceți iluzia că computerul face mai multe lucruri simultan.

Definiția Thread

Un fir este un singur flux secvențial de control.

Unii calificatori:

  • Un thread este o „cale de execuție” prin acel corp de cod.
  • Firele împărtășesc memoria, astfel încât trebuie să coopereze pentru a produce rezultatul corect.
  • Un thread conține date specifice thread-urilor, cum ar fi registre, indicatorul pentru stivă și contorul de programe.
  • Un proces este un singur corp de cod care poate avea multe fire, dar are cel puțin unul și are un singur context (spațiu de adrese).

Este vorba despre chestiuni la nivel de asamblare, dar în asta te apuci când începi să te gândești la fire.

Multitreading vs. multiprocesare

Multitreading nu este la fel ca procesarea paralelă multicore, dar multithreading și multiprocessing lucrează împreună. Majoritatea computerelor de astăzi au procesoare care au cel puțin două nuclee, iar mașinile obișnuite au uneori până la opt nuclee. Fiecare nucleu este un procesor separat, capabil să ruleze programe de la sine. Obțineți o îmbunătățire a performanței atunci când sistemul de operare alocă un proces diferit diferitelor nuclee. Utilizarea mai multor fire și mai multe procesoare pentru o performanță și mai mare se numește paralelism la nivel de fir.

O mare parte din ceea ce se poate face depinde de ceea ce poate face sistemul de operare și hardware-ul procesorului, nu întotdeauna ceea ce poți face în programul tău și nu ar trebui să te aștepți să poți folosi mai multe fire pe tot. De fapt, este posibil să nu găsiți multe probleme care beneficiază de mai multe fire. Deci, nu implementați multitreading doar pentru că este acolo. Puteți reduce cu ușurință performanța programului dvs. dacă nu este un candidat bun pentru multitratare. La fel ca exemple, codec-urile video pot fi cele mai proaste programe care pot fi citite mai mult, deoarece datele sunt in mod serial. Programele de server care se ocupă de paginile web ar putea fi printre cele mai bune, deoarece diferiții clienți sunt inerent independenți.

Exersarea siguranței firelor

Codul multitrat necesită adesea o coordonare complexă a firelor. Bug-urile subtile și dificil de găsit sunt frecvente, deoarece diferite fire de multe ori trebuie să partajeze aceleași date, astfel încât datele să poată fi schimbate cu un fir atunci când altul nu se așteaptă. Termenul general pentru această problemă este „starea cursei”. Cu alte cuvinte, cele două fire pot intra într-o „cursă” pentru a actualiza aceleași date, iar rezultatul poate fi diferit în funcție de ce fir „câștigă”. Ca un exemplu banal, să presupunem că codificați o buclă:

Dacă contorul buclei „I” lipsește în mod neașteptat numărul 7 și trece de la 6 la 8, dar numai o parte din timp, ar avea efecte dezastruoase asupra a ceea ce face bucla. Prevenirea problemelor de genul acesta se numește siguranță filetată. Dacă programul are nevoie de rezultatul unei operațiuni într-o operațiune ulterioară, atunci poate fi imposibil să codificați procese sau fire paralele pentru a o face. 

Operații de bază cu multitratare

Este timpul să împingeți această discuție de precauție pe fundal și să scrieți un cod multithreading. Acest articol utilizează o aplicație Console pentru simplitate acum. Dacă doriți să urmați, începeți Visual Studio cu un nou proiect de Console Application.

Spațiul principal de nume folosit de multithreading este spațiul de nume System.Threading și clasa Thread vor crea, porni și opri noi fire. În exemplul de mai jos, observați că TestMultiThreading este un delegat. Adică trebuie să folosiți numele unei metode pe care metoda Thread o poate apela.

În această aplicație, am putea să executăm cea de-a doua Sub, apelând-o pur și simplu:

Aceasta ar fi executat întreaga aplicație în mod serial. Cu toate acestea, primul exemplu de cod de deasupra pornește subrutina TestMultiThreading și apoi continuă.

Un exemplu de algoritm recurent

Iată o aplicație multithreaded care implică calcularea permutațiilor unui tablou folosind un algoritm recursiv. Nu toate codurile sunt prezentate aici. Matricea de caractere care este permisă este pur și simplu "1," "2", "3", "4" și "5." Iată partea relevantă a codului.