За да разберете резбата във VB.NET, това помага да се разберат някои от основните концепции. Първо е, че резбата е нещо, което се случва, защото операционната система го поддържа. Microsoft Windows е преимуществена многозадачна операционна система. Част от Windows, наречена планировчик на задачи, разделя време на процесора на всички работещи програми. Тези малки части от процесорното време се наричат времеви отрязъци. Програмите не са отговорни за това колко време получават процесорите, какъв е графикът на задачите. Тъй като тези времеви отрязъци са толкова малки, вие получавате илюзията, че компютърът прави няколко неща наведнъж.
Определение на нишката
Нишката е единичен последователен поток от контрол.
Някои квалификатори:
- Нишката е "път на изпълнение" през това тяло на код.
- Нишките споделят памет, така че те трябва да си сътрудничат, за да постигнат правилен резултат.
- Нишката има специфични за нишката данни като регистри, показател за стека и брояч на програмата.
- Процесът е единично тяло от код, което може да има много нишки, но има поне един и има един контекст (адресно пространство).
Това са неща на ниво сглобяване, но в това влизате, когато започнете да мислите за нишки.
Multithreading vs. многопроцесорна
Multithreading не е същото като многоядрената паралелна обработка, но многопоточната и многопроцесова работа работят заедно. Повечето компютри днес имат процесори, които имат поне две ядра, а обикновените домашни машини понякога имат до осем ядра. Всяко ядро е отделен процесор, способен сам да изпълнява програми. Повишавате производителността, когато ОС присвоява различен процес на различни ядра. Използването на множество нишки и множество процесори за още по-висока производителност се нарича паралелизъм на нишка.
Много от това, което може да се направи, зависи от това какво може да направи операционната система и хардуерът на процесора винаги какво можете да правите в програмата си и не бива да очаквате да можете да използвате няколко нишки всичко. Всъщност може да не намерите много проблеми, които се възползват от множество теми. Така че, не прилагайте многопоточност само защото е там. Можете лесно да намалите ефективността на вашата програма, ако не е добър кандидат за многопоточност. Точно като примери, видео кодеците може да са най-лошите програми за многопоточност, тъй като данните са присъщи сериен. Сървърните програми, които обработват уеб страници, може да са сред най-добрите, защото различните клиенти са по своята същност независими.
Практикуване на безопасността на резбата
Многопоточният код често изисква сложна координация на нишки. Тънките и трудно откриваеми грешки са често срещани, защото различните нишки често трябва да споделят едни и същи данни, така че данните могат да бъдат променени от една нишка, когато друга не я очаква. Общият термин за този проблем е „състояние на състезанието“. С други думи, двете нишки могат да влязат в „състезание“ за актуализиране на едни и същи данни и резултатът може да бъде различен в зависимост от това коя нишка „печели“. Като тривиален пример, да предположим, че кодирате цикъл:
Ако броячът на цикъла "I" неочаквано пропусне числото 7 и премине от 6 до 8 - но само в някои случаи - това би имало катастрофални ефекти върху каквото и да е цикълът. Предотвратяването на проблеми като този се нарича безопасност на резбата. Ако програмата се нуждае от резултата от една операция в по-късна операция, тогава може да бъде невъзможно да се кодират паралелни процеси или нишки, за да се направи.
Основни многопоточни операции
Време е да избутате този разговор за предпазливост на заден план и да напишете някакъв многопоточен код. Тази статия използва приложение за конзола за простота в момента. Ако искате да следвате, стартирайте Visual Studio с нов проект за приложение на конзолата.
Основното пространство на имена, използвано от многоредовото четене, е Системата. Пространството на имената на нишки и класът Thread ще създават, стартират и спират нови теми. В примера по-долу забележете, че TestMultiThreading е делегат. Тоест, трябва да използвате името на метод, който методът на Thread може да извика.
В това приложение можехме да изпълним втория Sub, като просто го извикахме:
Това би изпълнило цялото приложение по сериен начин. Първият пример на код по-горе обаче стартира подпрограмата TestMultiThreading и след това продължава.
Пример за рекурсивен алгоритъм
Ето едно многопоточно приложение, включващо изчисляване на пермутации на масив, използващ рекурсивен алгоритъм. Тук не е показан целият код. Масивът от пермутирани знаци е просто "1", "2", "3", "4" и "5." Ето съответната част от кода.
Забележете, че има два начина да се обадите на подс. Permute (и двете коментирани в кода по-горе). Единият започва от конец, а другият го извиква директно. Ако го позвъните директно, получавате:
Ако обаче стартирате нишка и вместо това стартирате подменю Permute, получавате:
Това ясно показва, че се генерира най-малко една пермутация, след това Главната подменю се придвижва напред и завършва, показвайки „Finished Main“, докато останалите permutation се генерират. Тъй като дисплеят идва от втори подвик, извикан от подстройката Permute, знаете, че това също е част от новата нишка. Това илюстрира концепцията, че нишката е "път на изпълнение", както беше споменато по-рано.
Пример за състезанието
Първата част на тази статия споменава състояние на състезанието. Ето пример, който го показва директно:
Незабавният прозорец показа този резултат в едно изпитание. Другите проучвания бяха различни. Това е същността на състоянието на състезанието.