Een inleiding tot Threading in VB.NET

Om threading in VB.NET te begrijpen, helpt het om enkele basisconcepten te begrijpen. Ten eerste is threading iets dat gebeurt omdat het besturingssysteem dit ondersteunt. Microsoft Windows is een preventief multitasking-besturingssysteem. Een deel van Windows genaamd de taakplanner verdeelt de processortijd naar alle actieve programma's. Deze kleine stukjes processortijd worden tijdschijven genoemd. Programma's zijn niet verantwoordelijk voor de hoeveelheid processortijd die ze krijgen, de taakplanner is. Omdat deze tijdschijven zo klein zijn, krijg je de illusie dat de computer verschillende dingen tegelijk doet.

Definitie van draad

Een thread is een enkele opeenvolgende controlestroom.

Enkele kwalificaties:

  • Een thread is een "pad van uitvoering" door die code.
  • Threads delen geheugen, zodat ze moeten samenwerken om het juiste resultaat te produceren.
  • Een thread heeft thread-specifieke gegevens zoals registers, een stapelwijzer en een programmateller.
  • Een proces is een enkele code die vele threads kan hebben, maar het heeft minstens één en het heeft een enkele context (adresruimte).

Dit zijn dingen op assemblageniveau, maar daar kom je bij als je begint na te denken over threads.

Multithreading versus multiprocessing

Multithreading is niet hetzelfde als multicore parallelle verwerking, maar multithreading en multiprocessing werken wel samen. De meeste pc's hebben tegenwoordig processors met ten minste twee cores en gewone thuismachines hebben soms tot acht cores. Elke kern is een afzonderlijke processor, die in staat is om zelf programma's te draaien. U krijgt een prestatieverbetering wanneer het besturingssysteem een ​​ander proces toewijst aan verschillende cores. Het gebruik van meerdere threads en meerdere processors voor nog betere prestaties wordt thread-level parallellisme genoemd.

Veel van wat er kan worden gedaan, hangt af van wat het besturingssysteem en de processorhardware kunnen doen, niet altijd wat u in uw programma kunt doen, en u zou niet moeten verwachten dat u meerdere threads op alles kunt gebruiken. In feite zult u misschien niet veel problemen vinden die profiteren van meerdere threads. Implementeer multithreading dus niet alleen omdat het er is. U kunt de prestaties van uw programma gemakkelijk verminderen als het geen goede kandidaat is voor multithreading. Net als voorbeelden kunnen videocodecs de slechtste programma's zijn om te multithreaden omdat de gegevens inherent serieel zijn. Serverprogramma's die webpagina's verwerken, behoren mogelijk tot de beste omdat de verschillende clients inherent onafhankelijk zijn.

Draadveiligheid oefenen

Multithreaded-code vereist vaak een complexe coördinatie van threads. Subtiele en moeilijk te vinden bugs komen vaak voor omdat verschillende threads vaak dezelfde gegevens moeten delen, zodat gegevens door de ene thread kunnen worden gewijzigd wanneer een andere deze niet verwacht. De algemene term voor dit probleem is "race condition". Met andere woorden, de twee threads kunnen deelnemen aan een "race" om dezelfde gegevens bij te werken en het resultaat kan verschillen, afhankelijk van welke thread "wint". Stel als een triviaal voorbeeld dat je een lus codeert:

Als de lusteller "I" onverwachts het cijfer 7 mist en van 6 naar 8 gaat - maar slechts een deel van de tijd - zou dit rampzalige gevolgen hebben voor alles wat de lus doet. Dit soort problemen voorkomen, wordt draadveiligheid genoemd. Als het programma het resultaat van een bewerking in een latere bewerking nodig heeft, kan het onmogelijk zijn om parallelle processen of threads te coderen om dit te doen. 

Basishandelingen voor multithreading

Het is tijd om dit voorzorgsgesprek naar de achtergrond te duwen en wat multithreading-code te schrijven. Dit artikel maakt voor het gemak nu gebruik van een consoletoepassing. Als u wilt volgen, start u Visual Studio met een nieuw Console Application-project.

De primaire naamruimte die door multithreading wordt gebruikt, is de naamruimte System.Threading en de klasse Thread maakt, start en stopt nieuwe threads. Merk in het onderstaande voorbeeld op dat TestMultiThreading een gemachtigde is. Dat wil zeggen, u moet de naam gebruiken van een methode die de Thread-methode kan aanroepen.

In deze app hadden we de tweede Sub kunnen uitvoeren door hem simpelweg te noemen:

Dit zou de hele applicatie serieel hebben uitgevoerd. Het eerste codevoorbeeld hierboven begint echter met de subroutine TestMultiThreading en gaat vervolgens verder.

Een recursief algoritme voorbeeld

Hier is een multithreadapplicatie waarbij permutaties van een array worden berekend met behulp van een recursief algoritme. Niet alle code wordt hier getoond. De reeks tekens die worden gepermuteerd, is eenvoudigweg "1", "2", "3", "4" en "5." Hier is het relevante deel van de code.