166
фдгдфгсдф фдгдфгсдф Съдържание Съдържание Многозадачност Многозадачност Нишки Нишки Синхронизация Синхронизация Асинхронни извиквания Асинхронни извиквания Забележка: Под някои Забележка: Под някои слайдове слайдове в полето забележки има в полето забележки има подробно описание на съдържанието на подробно описание на съдържанието на слайда слайда

Съдържание

Embed Size (px)

DESCRIPTION

Съдържание. Многозадачност Нишки Синхронизация Асинхронни извиквания Забележка: Под някои слайдове в полето забележки има подробно описание на съдържанието на слайда. Многозадачност – съдържание. Многозадачност Проблемът – защо многозадачност? Ползите от многозадачността - PowerPoint PPT Presentation

Citation preview

фдгдфгсдффдгдфгсдф

СъдържаниеСъдържание

МногозадачностМногозадачностНишкиНишкиСинхронизацияСинхронизацияАсинхронни извикванияАсинхронни извиквания

Забележка: Под някои Забележка: Под някои слайдовеслайдове в полето забележки има подробно в полето забележки има подробно описание на съдържанието на описание на съдържанието на слайдаслайда

фдгдфгсдффдгдфгсдф

Многозадачност – съдържаниеМногозадачност – съдържание МногозадачностМногозадачност

Проблемът – защо многозадачност?Проблемът – защо многозадачност? Ползите от многозадачносттаПолзите от многозадачността Решението – процеси и нишкиРешението – процеси и нишки Прилики и разликиПрилики и разлики Какво предлагат?Какво предлагат? Кога са удобни нишките?Кога са удобни нишките? Многозадачност – видовеМногозадачност – видове Имплементации на многозадачностИмплементации на многозадачност Application DomainsApplication Domains

НишкиНишки СинхронизацияСинхронизация Асинхронни извикванияАсинхронни извиквания

фдгдфгсдффдгдфгсдф

ПроблемътПроблемът

Има случаи, в които вашето приложение Има случаи, в които вашето приложение трябва да изпълни времеотнемащи трябва да изпълни времеотнемащи операции или да чака за освобождаването операции или да чака за освобождаването на ресурсна ресурс

Има случаи, в които вашето приложение Има случаи, в които вашето приложение трябва да извършва операция на заден трябва да извършва операция на заден планплан

Нужен е механизъм, който да позволява Нужен е механизъм, който да позволява няколко операции да се извършват няколко операции да се извършват едновременноедновременно

фдгдфгсдффдгдфгсдф

Ползите от многозадачносттаПолзите от многозадачността

Performance – на машината с няколко Performance – на машината с няколко процесора работи по-бързопроцесора работи по-бързо

ResponsivenessResponsiveness – системата отговаря – системата отговаря максимално бързо при интерактивна работамаксимално бързо при интерактивна работа

ThroughputThroughput – подобряване на – подобряване на производителността производителността Пример със супермаркета – обслужване на Пример със супермаркета – обслужване на

няколко каси едновременноняколко каси едновременно Обслужване на много потребители Обслужване на много потребители

едновременноедновременно

фдгдфгсдффдгдфгсдф

Демонстрация Демонстрация ##11

Защо е нужна многозадачностЗащо е нужна многозадачност

фдгдфгсдффдгдфгсдф

Решението –Решението – процеси и нишкипроцеси и нишки

Процесът представлява съвкупността от Процесът представлява съвкупността от памет, стек и кода на приложениетопамет, стек и кода на приложението

OSOS използват използват процесипроцеси ((process)process), за да , за да разграничават различните приложенияразграничават различните приложения

НишкатаНишката ((threadthread) ) е основната единица, на е основната единица, на която която OSOS може да заделя процесорно време може да заделя процесорно време

В един процес различните задачи се В един процес различните задачи се изпълняват от отделни нишкиизпълняват от отделни нишки

В един процес има поне една нишкаВ един процес има поне една нишка

фдгдфгсдффдгдфгсдф

Процес Процес vs.vs. Нишка Нишка

ПриликиПриликисобствен стек (собствен стек (stack)stack)приоритетприоритетexception handlersexception handlers

РазликиРазликиПроцесите са изолирани един от друг по Процесите са изолирани един от друг по

отношение на памет и данниотношение на памет и данниНишките в един процес споделят паметтаНишките в един процес споделят паметта

((променливите и даннитепроменливите и данните)) на този процес на този процесПроцесите съдържат изпълнимия код, а Процесите съдържат изпълнимия код, а

нишките го изпълняватнишките го изпълняват

фдгдфгсдффдгдфгсдф

Какво предлагат нишките?Какво предлагат нишките? Използването на няколко нишки Използването на няколко нишки

Създава впечатление за извършване на няколко Създава впечатление за извършване на няколко задачи едновременнозадачи едновременно

ПричинатаПричината:: Времето, през което една нишка Времето, през което една нишка държи процесора е много краткодържи процесора е много кратко

НапримерНапримерПотребителят може да въвежда данни в Потребителят може да въвежда данни в

текстообработваща програматекстообработваща програма докато се печатат докато се печатат данни на принтерданни на принтер

Би било недопустимо ако потребителят Би било недопустимо ако потребителят трябваше да изчака принтерът да свърши трябваше да изчака принтерът да свърши работата сиработата си

фдгдфгсдффдгдфгсдф

Кога са удобни нишките?Кога са удобни нишките?

Случаи, в които е удобно да се използват Случаи, в които е удобно да се използват нишки:нишки:Обслужване на много потребители Обслужване на много потребители

едновременно, например едновременно, например WebWeb сървър сървърКомуникация през мрежаКомуникация през мрежа (sockets) (sockets)Извършване на времеотнемаща операцияИзвършване на времеотнемаща операцияРазличаване на задачите по приоритетРазличаване на задачите по приоритетЗа да може потребителският интерфейс да За да може потребителският интерфейс да

продължи да “откликва” на потребителски продължи да “откликва” на потребителски заявки, докато на заден план се извършва заявки, докато на заден план се извършва друга задачадруга задача

фдгдфгсдффдгдфгсдф

Многозадачност – Изпреварваща Многозадачност – Изпреварваща и кооперативнаи кооперативна

Кооперативна многозадачност (cooperative Кооперативна многозадачност (cooperative multitasking)multitasking) Нишката сНишката сама решава колко процесорно време ама решава колко процесорно време

йй е необходимо е необходимо Сваля Сваля се се от процесора само ако е свършила от процесора само ако е свършила

или или чака за някакъв ресурсчака за някакъв ресурс Изпреварваща многозадачност (Изпреварваща многозадачност (preemptive preemptive

multitasking)multitasking) Планировчикът (Планировчикът (task scheduler) task scheduler) заделя заделя

предварително някакво процесорно времепредварително някакво процесорно време Без значение дали е приключила, нишката се Без значение дали е приключила, нишката се

снема от процесораснема от процесора

фдгдфгсдффдгдфгсдф

Многозадачност – Изпреварваща Многозадачност – Изпреварваща и кооперативнаи кооперативна

При кооперативната многозадачност:При кооперативната многозадачност:Една нишка може дълго време да държи Една нишка може дълго време да държи

процесорапроцесораЗаради нея останалите нишки могат да чакат Заради нея останалите нишки могат да чакат

недопустимо дългонедопустимо дълго Някои системи използват комбиниран Някои системи използват комбиниран

вариантвариантНишки с висок приоритет се държат кооперативно Нишки с висок приоритет се държат кооперативно

спрямо нишките с по-нисък приоритетспрямо нишките с по-нисък приоритет

фдгдфгсдффдгдфгсдф

Имплементации на многозадачностИмплементации на многозадачност

ApartmentApartment

Global DataGlobal Data

InstructionInstruction

InstructionInstruction

ThreadThread

ApartmentApartment

Global DataGlobal Data

InstructionInstruction

InstructionInstruction

ThreadThread

InstructionInstruction

InstructionInstruction

ThreadThread

InstructionInstruction

InstructionInstruction

ThreadThread

ProcessProcess

Global DataGlobal Data

Apartment ThreadingApartment Threading Free ThreadingFree Threading

фдгдфгсдффдгдфгсдф

Application DomainApplication Domain

.NET Framework добавя още едно ниво на абстракция .NET Framework добавя още едно ниво на абстракция между нишка и процес – Application Domainмежду нишка и процес – Application Domain

AppDomain-ът дава логическа изолацияAppDomain-ът дава логическа изолация При процесите изолацията е физическа, тъй като е При процесите изолацията е физическа, тъй като е

имплементиран на ниво OSимплементиран на ниво OS

ПредимстваПредимства Подобрена производителностПодобрена производителност Ниво на изолация –Ниво на изолация – като при процесакато при процеса Връзка м/у нишки без proxyВръзка м/у нишки без proxy Извършва type checkingИзвършва type checking

System.AppDomainSystem.AppDomain

фдгдфгсдффдгдфгсдф

System.AppDomainSystem.AppDomain

AppDomain #1AppDomain #1

Global DataGlobal Data

InstructionInstruction

ThreadThread

AppDomain #2AppDomain #2

InstructionInstruction

ThreadThread

InstructionInstruction

ThreadThreadAppDomain #4AppDomain #4

Global DataGlobal Data

AppDomain #3AppDomain #3

Global DataGlobal Data

InstructionInstruction

ThreadThread

фдгдфгсдффдгдфгсдф

Нишки – съдържаниеНишки – съдържание МногозадачностМногозадачност НишкиНишки

Как работят нишкитеКак работят нишките Живот на нишкитеЖивот на нишките По-важни членовеПо-важни членове ПриоритетПриоритет СъстоянияСъстояния ThreadThread LocalLocal StorageStorage Thread-Relative Static FieldsThread-Relative Static Fields ПрекратяванеПрекратяване НеудобстваНеудобства Повреждане на данниПовреждане на данни

СинхронизацияСинхронизация Асинхронни извикванияАсинхронни извиквания

фдгдфгсдффдгдфгсдф

Как работи многонишковосттаКак работи многонишковостта

InstructionInstruction

InstructionInstruction

InstructionInstruction

InstructionInstruction

InterruptInterrupt

Tim

e S

lice

Tim

e S

lice

ThreadThread

ThreadThread

ThreadThread

ThreadThread

ThreadThread

Ru

nn

ing

Qu

eue

Ru

nn

ing

Qu

eue

Return to QueueReturn to Queue

Pull From QueuePull From Queue

фдгдфгсдффдгдфгсдф

Малък примерМалък примерclass FirstThread {class FirstThread { public void public void DDoTask1() {oTask1() { for( int i=0; i<100; i++ )for( int i=0; i<100; i++ ) Console.WriteLine("Thread1:job({0})",i);Console.WriteLine("Thread1:job({0})",i); }} public void public void DDoTask2() {oTask2() { for( int i=0; i<100; i++ )for( int i=0; i<100; i++ ) Console.WriteLine("Thread2:job({0})",i);Console.WriteLine("Thread2:job({0})",i); }}}}class Starter {class Starter { static void Main(string[] args) {static void Main(string[] args) { FirstThread ft = new FirstThread();FirstThread ft = new FirstThread(); Thread t1 = new Thread(Thread t1 = new Thread( new ThreadStart(ft.new ThreadStart(ft.DDoTask1));oTask1)); Thread t2 = new Thread(Thread t2 = new Thread( new ThreadStart(ft.new ThreadStart(ft.DDoTask2));oTask2)); t1.Start();t1.Start(); t2.Start();t2.Start(); }}}}

фдгдфгсдффдгдфгсдф

Малък примерМалък примерclass FirstThread {class FirstThread { public void public void DDoTask1() {oTask1() { for( int i=0; i<100; i++ )for( int i=0; i<100; i++ ) Console.WriteLine("Thread1:job({0})",i);Console.WriteLine("Thread1:job({0})",i); }} public void public void DDoTask2() {oTask2() { for( int i=0; i<100; i++ )for( int i=0; i<100; i++ ) Console.WriteLine("Thread2:job({0})",i);Console.WriteLine("Thread2:job({0})",i); }}}}class Starter {class Starter { static void Main(string[] args) {static void Main(string[] args) { FirstThread ft = new FirstThread();FirstThread ft = new FirstThread(); Thread t1 = new Thread(Thread t1 = new Thread( new ThreadStart(ft.new ThreadStart(ft.DDoTask1));oTask1)); Thread t2 = new Thread(Thread t2 = new Thread( new ThreadStart(ft.new ThreadStart(ft.DDoTask2));oTask2)); t1.Start();t1.Start(); t2.Start();t2.Start(); }}}}

фдгдфгсдффдгдфгсдф

Малък примерМалък примерclass FirstThread {class FirstThread { public void public void DDoTask1() {oTask1() { for( int i=0; i<100; i++ )for( int i=0; i<100; i++ ) Console.WriteLine("Thread1:job({0})",i);Console.WriteLine("Thread1:job({0})",i); }} public void public void DDoTask2() {oTask2() { for( int i=0; i<100; i++ )for( int i=0; i<100; i++ ) Console.WriteLine("Thread2:job({0})",i);Console.WriteLine("Thread2:job({0})",i); }}}}class Starter {class Starter { static void Main(string[] args) {static void Main(string[] args) { FirstThread ft = new FirstThread();FirstThread ft = new FirstThread(); Thread t1 = new Thread(Thread t1 = new Thread( new ThreadStart(ft.new ThreadStart(ft.DDoTask1)oTask1));); Thread t2 = new Thread(Thread t2 = new Thread( new ThreadStart(ft.new ThreadStart(ft.DDoTask2));oTask2)); t1.Start();t1.Start(); t2.Start();t2.Start(); }}}}

фдгдфгсдффдгдфгсдф

Малък примерМалък примерclass FirstThread {class FirstThread { public void public void DDoTask1() {oTask1() { for( int i=0; i<100; i++ )for( int i=0; i<100; i++ ) Console.WriteLine("Thread1:job({0})",i);Console.WriteLine("Thread1:job({0})",i); }} public void public void DDoTask2() {oTask2() { for( int i=0; i<100; i++ )for( int i=0; i<100; i++ ) Console.WriteLine("Thread2:job({0})",i);Console.WriteLine("Thread2:job({0})",i); }}}}class Starter {class Starter { static void Main(string[] args) {static void Main(string[] args) { FirstThread ft = new FirstThread();FirstThread ft = new FirstThread(); Thread t1 = new Thread(Thread t1 = new Thread( new ThreadStart(new ThreadStart(ft.ft.DDoTask1oTask1)));); Thread t2 = new Thread(Thread t2 = new Thread( new ThreadStart(ft.new ThreadStart(ft.DDoTask2));oTask2)); t1.Start();t1.Start(); t2.Start();t2.Start(); }}}}

фдгдфгсдффдгдфгсдф

Малък примерМалък примерclass FirstThread {class FirstThread { public void public void DDoTask1() {oTask1() { for( int i=0; i<100; i++ )for( int i=0; i<100; i++ ) Console.WriteLine("Thread1:job({0})",i);Console.WriteLine("Thread1:job({0})",i); }} public void public void DDoTask2() {oTask2() { for( int i=0; i<100; i++ )for( int i=0; i<100; i++ ) Console.WriteLine("Thread2:job({0})",i);Console.WriteLine("Thread2:job({0})",i); }}}}class Starter {class Starter { static void Main(string[] args) {static void Main(string[] args) { FirstThread ft = new FirstThread();FirstThread ft = new FirstThread(); Thread t1 = new Thread(Thread t1 = new Thread( new ThreadStart(new ThreadStart(ft.ft.DDoTask1oTask1));)); Thread t2 = new Thread(Thread t2 = new Thread( new ThreadStart(ft.new ThreadStart(ft.DDoTask2));oTask2)); t1.Start();t1.Start(); t2.Start();t2.Start(); }}}}

фдгдфгсдффдгдфгсдф

Малък примерМалък примерclass FirstThread {class FirstThread { public void public void DDoTask1() {oTask1() { for( int i=0; i<100; i++ )for( int i=0; i<100; i++ ) Console.WriteLine("Thread1:job({0})",i);Console.WriteLine("Thread1:job({0})",i); }} public void public void DDoTask2() {oTask2() { for( int i=0; i<100; i++ )for( int i=0; i<100; i++ ) Console.WriteLine("Thread2:job({0})",i);Console.WriteLine("Thread2:job({0})",i); }}}}class Starter {class Starter { static void Main(string[] args) {static void Main(string[] args) { FirstThread ft = new FirstThread();FirstThread ft = new FirstThread(); Thread t1 = new Thread(Thread t1 = new Thread( new ThreadStart(ft.new ThreadStart(ft.DDoTask1));oTask1)); Thread t2 = new Thread(Thread t2 = new Thread( new ThreadStart(ft.new ThreadStart(ft.DDoTask2));oTask2)); t1.Start();t1.Start(); t2.Start();t2.Start(); }}}}

фдгдфгсдффдгдфгсдф

Малък примерМалък примерclass FirstThread {class FirstThread { public void public void DDoTask1() {oTask1() { for( int i=0; i<100; i++ )for( int i=0; i<100; i++ ) Console.WriteLine("Thread1:job({0})",i);Console.WriteLine("Thread1:job({0})",i); }} public void public void DDoTask2() {oTask2() { for( int i=0; i<100; i++ )for( int i=0; i<100; i++ ) Console.WriteLine("Thread2:job({0})",i);Console.WriteLine("Thread2:job({0})",i); }}}}class Starter {class Starter { static void Main(string[] args) {static void Main(string[] args) { FirstThread ft = new FirstThread();FirstThread ft = new FirstThread(); Thread t1 = new Thread(Thread t1 = new Thread( new ThreadStart(ft.new ThreadStart(ft.DDoTask1));oTask1)); Thread t2 = new Thread(Thread t2 = new Thread( new ThreadStart(ft.new ThreadStart(ft.DDoTask2));oTask2)); t1.Start();t1.Start(); t2.Start();t2.Start(); }}}}

фдгдфгсдффдгдфгсдф

Малък примерМалък пример//Резултат://Резултат:Thread1:job(1)Thread1:job(1)Thread1:job(2)Thread1:job(2)Thread2:job(1)Thread2:job(1)Thread1:job(3)Thread1:job(3)............Thread1:job(53)Thread1:job(53)Thread2:job(46)Thread2:job(46)Thread2:job(47)Thread2:job(47)Thread1:job(54)Thread1:job(54)............Thread1:job(97)Thread1:job(97)Thread2:job(99)Thread2:job(99)Thread1:job(98)Thread1:job(98)Thread1:job(99)Thread1:job(99)

фдгдфгсдффдгдфгсдф

Демонстрация #Демонстрация #22

Нишки – малък примерНишки – малък пример

фдгдфгсдффдгдфгсдф

Жизнен цикъл на нишкитеЖизнен цикъл на нишкитеStart()Start()

IsAlive

Suspend()Suspend() Sleep()Sleep() WaitX()WaitX() Join()Join()

ThreadThreadStoppedStopped

Suspended WaitSleepJoin WaitSleepJoin WaitSleepJoin Stopped

Interrupt()Interrupt() AimedAimedThreadThread

DestroyedDestroyed

Interrupt()Interrupt()

Resume()Resume()

All Done

Abort()Abort()

Expire timeExpire time NotifiedNotified

фдгдфгсдффдгдфгсдф

По-важните членове на По-важните членове на ThreadThreadpublic Thread( ThreadStart );public Thread( ThreadStart );

Създава инстанцияСъздава инстанцияПодава се делегат с метод, който да се Подава се делегат с метод, който да се

изпълни при стартиранеизпълни при стартиране Sleep()Sleep() Suspend()Suspend() Resume()Resume() IsAliveIsAlive IsBackgroundIsBackground IsThreadPoolThreadIsThreadPoolThread NameName PriorityPriority ThreadStateThreadState Abort()Abort() Interrupt()Interrupt() Join()Join() Start()Start()

фдгдфгсдффдгдфгсдф

По-важните членове на По-важните членове на ThreadThread public Thread( ThreadStart start);public Thread( ThreadStart start);

Sleep()Sleep() ““Приспива” текущата нишка за указания брой Приспива” текущата нишка за указания брой

милисекунди (и наносекунди)милисекунди (и наносекунди)Извиква се само от самата нишкаИзвиква се само от самата нишка

Suspend()Suspend() Resume()Resume() IsAliveIsAlive IsBackgroundIsBackground IsThreadPoolThreadIsThreadPoolThread NameName PriorityPriority ThreadStateThreadState Abort()Abort() Interrupt()Interrupt() Join()Join() Start()Start()

фдгдфгсдффдгдфгсдф

Малко повече за Малко повече за Sleep()Sleep()InstructionInstruction

InstructionInstruction

InstructionInstruction

InstructionInstruction

Sleep()Sleep()

Sle

ep Q

ueu

eS

leep

Qu

eue

ThreadThread

ThreadThread

ThreadThread

ThreadThread

ThreadThread

Ru

nn

ing

Qu

eue

Ru

nn

ing

Qu

eue

Clock InterruptClock Interruptfr

om

Qu

eue

fro

m Q

ueu

e

TT

TT

TT

TT

TT

To

Sle

ep Q

ueu

eT

o S

leep

Qu

eue

фдгдфгсдффдгдфгсдф

Приспиване на нишкаПриспиване на нишкаusing System;using System;using System.Threading;using System.Threading;public class ThreadSleeppublic class ThreadSleep{{ public static Thread worker;public static Thread worker; public static Thread worker2;public static Thread worker2; public static void Main()public static void Main() {{ Console.WriteLine("Entering void Main!");Console.WriteLine("Entering void Main!"); worker = new Thread(newworker = new Thread(new ThreadStart(Counter));ThreadStart(Counter)); worker2 = new Thread(newworker2 = new Thread(new ThreadStart(Counter2));ThreadStart(Counter2)); worker.Start();worker.Start(); worker2.Start();worker2.Start(); Console.WriteLine("Exiting void Main!");Console.WriteLine("Exiting void Main!"); }} (примерът продължава)(примерът продължава)

фдгдфгсдффдгдфгсдф

Приспиване на нишкаПриспиване на нишка public static void Counter()public static void Counter() {{ Console.WriteLine("Entering Counter");Console.WriteLine("Entering Counter"); for(int i = 1; i < 50; i++)for(int i = 1; i < 50; i++) {{ Console.Write(i + " ");Console.Write(i + " "); if(i == 10)if(i == 10) Thread.Sleep(1000);Thread.Sleep(1000); }} Console.WriteLine("Console.WriteLine("\n\nExiting Counter");Exiting Counter"); }} public static void Counter2()public static void Counter2() {{ Console.WriteLine("Entering Counter2");Console.WriteLine("Entering Counter2"); for(int i = 51; i < 100; i++)for(int i = 51; i < 100; i++) {{ Console.Write(i + " "); Console.Write(i + " "); if( i == 70 )if( i == 70 ) Thread.Sleep(5000);Thread.Sleep(5000); }} Console.WriteLine(“Console.WriteLine(“\n\nExiting Counter2");Exiting Counter2"); }}}}

фдгдфгсдффдгдфгсдф

Демонстрация #Демонстрация #33

Използване на Използване на Thread.Sleep()Thread.Sleep()

фдгдфгсдффдгдфгсдф

По-важните членове на По-важните членове на ThreadThread public Thread( ThreadStart start);public Thread( ThreadStart start); Sleep()Sleep()Suspend()Suspend()

Ако нишката е в състояние Ако нишката е в състояние RunningRunning, я , я преустановява временно (suspend)преустановява временно (suspend)

ако е преустановена, не се случва нищоако е преустановена, не се случва нищо Resume()Resume() IsAliveIsAlive IsBackgroundIsBackground IsThreadPoolThreadIsThreadPoolThread NameName PriorityPriority ThreadStateThreadState Abort()Abort() Interrupt()Interrupt() Join()Join() Start()Start()

фдгдфгсдффдгдфгсдф

По-важните членове на По-важните членове на ThreadThread public Thread( ThreadStart start);public Thread( ThreadStart start); Sleep()Sleep() Suspend()Suspend()Resume()Resume()

Подновява нишка, която е била Подновява нишка, която е била преустановена (suspended)преустановена (suspended)

Ако нишката работи, не прави нищоАко нишката работи, не прави нищо IsAliveIsAlive IsBackgroundIsBackground IsThreadPoolThreadIsThreadPoolThread NameName PriorityPriority ThreadStateThreadState Abort()Abort() Interrupt()Interrupt() Join()Join() Start()Start()

фдгдфгсдффдгдфгсдф

Демонстрация #Демонстрация #44

Използване на Използване на SuspendSuspend()() и и ResumeResume()()

фдгдфгсдффдгдфгсдф

По-важните членове на По-важните членове на ThreadThread public Thread( ThreadStart start);public Thread( ThreadStart start); Sleep()Sleep() Suspend()Suspend() Resume()Resume()IsAliveIsAlive

truetrue, ако е стартирана и не е спряна , ако е стартирана и не е спряна прекъсната или прекратенапрекъсната или прекратена

Повече информация дава Повече информация дава ThreadStateThreadState IsBackgroundIsBackground IsThreadPoolThreadIsThreadPoolThread NameName PriorityPriority ThreadStateThreadState Abort()Abort() Interrupt()Interrupt() Join()Join() Start()Start()

фдгдфгсдффдгдфгсдф

По-важните членове на По-важните членове на ThreadThread public Thread( ThreadStart start);public Thread( ThreadStart start); Sleep()Sleep() Suspend()Suspend() Resume()Resume() IsAliveIsAliveIsBackgroundIsBackground

Преден план (foreground) и фонов режим Преден план (foreground) и фонов режим (background)(background)

Свойство за смяна/извличанеСвойство за смяна/извличане IsThreadPoolThreadIsThreadPoolThread NameName PriorityPriority ThreadStateThreadState Abort()Abort() Interrupt()Interrupt() Join()Join() Start()Start()

фдгдфгсдффдгдфгсдф

По-важните членове на По-важните членове на ThreadThread public Thread( ThreadStart start);public Thread( ThreadStart start); Sleep()Sleep() Suspend()Suspend() Resume()Resume() IsAliveIsAlive IsBackgroundIsBackgroundIsThreadPoolThreadIsThreadPoolThread

Свойство за смяна/извличанеСвойство за смяна/извличанеtruetrue, ако нишката принадлежи на managed , ако нишката принадлежи на managed

thread pool, иначе thread pool, иначе falsefalse NameName PriorityPriority ThreadStateThreadState Abort()Abort() Interrupt()Interrupt() Join()Join() Start()Start()

фдгдфгсдффдгдфгсдф

По-важните членове на По-важните членове на ThreadThread public Thread( ThreadStart start);public Thread( ThreadStart start); Sleep()Sleep() Suspend()Suspend() Resume()Resume() IsAliveIsAlive IsBackgroundIsBackground IsThreadPoolThreadIsThreadPoolThreadNameName

Всяка нишка в Всяка нишка в .NET Framework.NET Framework може може да има имеда има име

Свойство за смяна/извличанеСвойство за смяна/извличане на иметона името PriorityPriority ThreadStateThreadState Abort()Abort() Interrupt()Interrupt() Join()Join() Start()Start()

фдгдфгсдффдгдфгсдф

По-важните членове на По-важните членове на ThreadThread public Thread( ThreadStart start);public Thread( ThreadStart start); Sleep()Sleep() Suspend()Suspend() Resume()Resume() IsAliveIsAlive IsBackgroundIsBackground IsThreadPoolThreadIsThreadPoolThread NameNamePriorityPriority

LowestLowest, , BelowNormalBelowNormal, , NormalNormal (по (по подразбиране), подразбиране), AboveNormalAboveNormal, , HighestHighest

Свойство за промяна/извличанеСвойство за промяна/извличане ThreadStateThreadState Abort()Abort() Interrupt()Interrupt() Join()Join() Start()Start()

фдгдфгсдффдгдфгсдф

По-важните членове на По-важните членове на ThreadThread public Thread( ThreadStart start);public Thread( ThreadStart start); Sleep()Sleep() Suspend()Suspend() Resume()Resume() IsAliveIsAlive IsBackgroundIsBackground IsThreadPoolThreadIsThreadPoolThread NameName PriorityPriorityThreadStateThreadState

Съдържа състоянието на нишката – зависи Съдържа състоянието на нишката – зависи от това дали нишката работиот това дали нишката работи

Свойство само за извличанеСвойство само за извличане Abort()Abort() Interrupt()Interrupt() Join()Join() Start()Start()

фдгдфгсдффдгдфгсдф

По-важните членове на По-важните членове на ThreadThread public Thread( ThreadStart start);public Thread( ThreadStart start); Sleep()Sleep() Suspend()Suspend() Resume()Resume() IsAliveIsAlive IsBackgroundIsBackground IsThreadPoolThreadIsThreadPoolThread NameName PriorityPriority ThreadStateThreadStateAbort()Abort()

Обикновено “убива” нишкатаОбикновено “убива” нишкатаХвърля Хвърля ThreadAbortExceptionThreadAbortException в в

извиканата нишкаизвиканата нишка Interrupt()Interrupt() Join()Join() Start()Start()

фдгдфгсдффдгдфгсдф

По-важните членове на По-важните членове на ThreadThread public Thread( ThreadStart start);public Thread( ThreadStart start); Sleep()Sleep() Suspend()Suspend() Resume()Resume() IsAliveIsAlive IsBackgroundIsBackground IsThreadPoolThreadIsThreadPoolThread NameName PriorityPriority ThreadStateThreadState Abort()Abort()Interrupt()Interrupt()

Събужда нишка ако е в състояние Събужда нишка ако е в състояние WaitSleepJoinWaitSleepJoin, иначе не прави нищо, иначе не прави нищо

Хвърля Хвърля ThreadInterruptedExceptionThreadInterruptedException Join()Join() Start()Start()

фдгдфгсдффдгдфгсдф

По-важните членове на По-важните членове на ThreadThread public Thread( ThreadStart start);public Thread( ThreadStart start); Sleep()Sleep() Suspend()Suspend() Resume()Resume() IsAliveIsAlive IsBackgroundIsBackground IsThreadPoolThreadIsThreadPoolThread NameName PriorityPriority ThreadStateThreadState Abort()Abort() Interrupt()Interrupt()Join()Join()

Извикващата нишка изчаква, докато Извикващата нишка изчаква, докато извиканата приключиизвиканата приключи

Може да се укаже таймаут (timeout)Може да се укаже таймаут (timeout) Start()Start()

фдгдфгсдффдгдфгсдф

Демонстрация #Демонстрация #55

Използване на Използване на Thread.Join()Thread.Join()

фдгдфгсдффдгдфгсдф

По-важните членове на По-важните членове на ThreadThread public Thread( ThreadStart start);public Thread( ThreadStart start); Sleep()Sleep() Suspend()Suspend() Resume()Resume() IsAliveIsAlive IsBackgroundIsBackground IsThreadPoolThreadIsThreadPoolThread NameName PriorityPriority ThreadStateThreadState Abort()Abort() Interrupt()Interrupt() Join()Join()Start()Start()

Стартира посочената нишкаСтартира посочената нишкаОперацията не е блокираща (връща Операцията не е блокираща (връща

управлението веднага)управлението веднага)

фдгдфгсдффдгдфгсдф

Приоритет на нишкаПриоритет на нишка

Повечето имплементации на многонишковост Повечето имплементации на многонишковост включват отличителното качество "приоритет"включват отличителното качество "приоритет" Приоритетът указва колко важна е нишката (колко време Приоритетът указва колко важна е нишката (колко време

да й се отделя)да й се отделя) Важен е за планировчика (Важен е за планировчика (task scheduler) task scheduler)

Приоритетът в Приоритетът в .NET Framework.NET Framework Възможни стойностиВъзможни стойности

LowestLowest, , BelowNormalBelowNormal, , NormalNormal ( (по подразбиране), по подразбиране), AboveNormalAboveNormal, , HighestHighest

В В Win32 Win32 има и приоритет има и приоритет RealTimeRealTime OSOS не е длъжна да се съобразява с приоритета на не е длъжна да се съобразява с приоритета на

нишките, но обикновено го правинишките, но обикновено го прави

фдгдфгсдффдгдфгсдф

ПриоритетПриоритет – – примерпримерclass FirstThread {class FirstThread { public void DoTask1() {public void DoTask1() { for( int i=0; i<100; i++ )for( int i=0; i<100; i++ ) Console.WriteLine("Thread1:job({0})",i);Console.WriteLine("Thread1:job({0})",i); }} public void DoTask2() {public void DoTask2() { for( int i=0; i<100; i++ )for( int i=0; i<100; i++ ) Console.WriteLine("Thread2:job({0})",i);Console.WriteLine("Thread2:job({0})",i); }}}}class Starterclass Starter static void Main(string[] args) {static void Main(string[] args) { FirstThread ft = new FirstThread();FirstThread ft = new FirstThread(); Thread t1 = new Thread(Thread t1 = new Thread( new ThreadStart(ft.DoTask1));new ThreadStart(ft.DoTask1)); Thread t2 = new Thread(Thread t2 = new Thread( new ThreadStart(ft.DoTask2));new ThreadStart(ft.DoTask2)); t1.Priority = ThreadPriority.Highest;t1.Priority = ThreadPriority.Highest; t1.Start();t1.Start(); t2.Start();t2.Start(); }}}}

фдгдфгсдффдгдфгсдф

ПриоритетПриоритетРезултат:Резултат:Thread1:job(1)Thread1:job(1)Thread1:job(2)Thread1:job(2)Thread2:job(1)Thread2:job(1)Thread1:job(3)Thread1:job(3)............Thread1:job(97)Thread1:job(97)Thread1:job(98)Thread1:job(98)Thread2:job(85)Thread2:job(85)Thread1:job(99)Thread1:job(99)Thread2:job(86)Thread2:job(86)............Thread2:job(97)Thread2:job(97)Thread2:job(98)Thread2:job(98)Thread2:job(99)Thread2:job(99)

фдгдфгсдффдгдфгсдф

ThreadStateThreadState Всяка нишка във всеки един момент е в някое от Всяка нишка във всеки един момент е в някое от

състоянията на енумерацията състоянията на енумерацията ThreadStateThreadState Допуска се да бъде в няколко състояния Допуска се да бъде в няколко състояния

едновременноедновременно Енумерацията има атрибут Енумерацията има атрибут FlagsAttributeFlagsAttribute

Това позволява побитово комбиниране на стойностите Това позволява побитово комбиниране на стойностите й:й:

if ((state & (Unstarted | Stopped)) == 0) if ((state & (Unstarted | Stopped)) == 0)

// implies Running// implies Running

Когато се създаде нишка е в състояние Когато се създаде нишка е в състояние UnstartedUnstarted Остава така докато не се извика Остава така докато не се извика StartStart()()

фдгдфгсдффдгдфгсдф

Състоянията в Състоянията в ThreadStateThreadStateAborted(256)Aborted(256)

Извикан е метода Извикан е метода Abort()Abort()Нишката е в състояние Нишката е в състояние StoppedStopped, ,

едновременно с едновременно с AbortedAborted AbortRequested(128)AbortRequested(128) Background(4)Background(4) Running(0)Running(0) Stopped(16)Stopped(16) StopRequested(1)StopRequested(1) Suspended(64)Suspended(64) SuspendRequested(2)SuspendRequested(2) Unstarted(8)Unstarted(8) WaitSleepJoin(32)WaitSleepJoin(32)

фдгдфгсдффдгдфгсдф

Състоянията в Състоянията в ThreadStateThreadState Aborted(256)Aborted(256)AbortRequested(128)AbortRequested(128)

Методът Методът Abort()Abort() е бил извикане бил извиканОще не е получила Още не е получила ThreadAbortExceptionThreadAbortException, ,

което ще се опита да я прекратикоето ще се опита да я прекрати Background(4)Background(4) Running(0)Running(0) Stopped(16)Stopped(16) StopRequested(1)StopRequested(1) Suspended(64)Suspended(64) SuspendRequested(2)SuspendRequested(2) Unstarted(8)Unstarted(8) WaitSleepJoin(32)WaitSleepJoin(32)

фдгдфгсдффдгдфгсдф

Състоянията в Състоянията в ThreadStateThreadState Aborted(256)Aborted(256) AbortRequested(128)AbortRequested(128)Background(4)Background(4)

Нишката е във фонов режимНишката е във фонов режимПроменя се със свойството Променя се със свойството Thread.IsBackgroundThread.IsBackground

Running(0)Running(0) Stopped(16)Stopped(16) StopRequested(1)StopRequested(1) Suspended(64)Suspended(64) SuspendRequested(2)SuspendRequested(2) Unstarted(8)Unstarted(8) WaitSleepJoin(32)WaitSleepJoin(32)

фдгдфгсдффдгдфгсдф

Състоянията в Състоянията в ThreadStateThreadState Aborted(256)Aborted(256) AbortRequested(128)AbortRequested(128) Background(4)Background(4)Running(0)Running(0)

Нишката е стартирана и не е блокиранаНишката е стартирана и не е блокиранаНяма чакащо изключение Няма чакащо изключение ThreadAbortedExceptionThreadAbortedException

Stopped(16)Stopped(16) StopRequested(1)StopRequested(1) Suspended(64)Suspended(64) SuspendRequested(2)SuspendRequested(2) Unstarted(8)Unstarted(8) WaitSleepJoin(32)WaitSleepJoin(32)

фдгдфгсдффдгдфгсдф

Състоянията в Състоянията в ThreadStateThreadState Aborted(256)Aborted(256) AbortRequested(128)AbortRequested(128) Background(4)Background(4) Running(0)Running(0)Stopped(16)Stopped(16)

Нишката е отговорила на заявка от Нишката е отговорила на заявка от Abort()Abort() илиили

Прекратила е работата си доброволноПрекратила е работата си доброволно StopRequested(1)StopRequested(1) Suspended(64)Suspended(64) SuspendRequested(2)SuspendRequested(2) Unstarted(8)Unstarted(8) WaitSleepJoin(32)WaitSleepJoin(32)

фдгдфгсдффдгдфгсдф

Състоянията в Състоянията в ThreadStateThreadState Aborted(256)Aborted(256) AbortRequested(128)AbortRequested(128) Background(4)Background(4) Running(0)Running(0) Stopped(16)Stopped(16)StopRequested(1)StopRequested(1)

Поискано е било от нишката да спре работаПоискано е било от нишката да спре работаСамо за вътрешна употребаСамо за вътрешна употреба

Suspended(64)Suspended(64) SuspendRequested(2)SuspendRequested(2) Unstarted(8)Unstarted(8) WaitSleepJoin(32)WaitSleepJoin(32)

фдгдфгсдффдгдфгсдф

Състоянията в Състоянията в ThreadStateThreadState Aborted(256)Aborted(256) AbortRequested(128)AbortRequested(128) Background(4)Background(4) Running(0)Running(0) Stopped(16)Stopped(16) StopRequested(1)StopRequested(1)Suspended(64)Suspended(64)

Нишката е била преустановенаНишката е била преустановенаНезависимо колко пъти е извикан Независимо колко пъти е извикан Suspend()Suspend(), ,

един един Resume()Resume() е достатъчене достатъчен SuspendRequested(2)SuspendRequested(2) Unstarted(8)Unstarted(8) WaitSleepJoin(32)WaitSleepJoin(32)

фдгдфгсдффдгдфгсдф

Състоянията в Състоянията в ThreadStateThreadState Aborted(256)Aborted(256) AbortRequested(128)AbortRequested(128) Background(4)Background(4) Running(0)Running(0) Stopped(16)Stopped(16) StopRequested(1)StopRequested(1) Suspended(64)Suspended(64)SuspendRequested(2)SuspendRequested(2)

Извикан е метода Извикан е метода Suspend()Suspend()Изчаква се да стигне до стабилно състояние, Изчаква се да стигне до стабилно състояние,

за да се преустановиза да се преустанови Unstarted(8)Unstarted(8) WaitSleepJoin(32)WaitSleepJoin(32)

фдгдфгсдффдгдфгсдф

Състоянията в Състоянията в ThreadStateThreadState Aborted(256)Aborted(256) AbortRequested(128)AbortRequested(128) Background(4)Background(4) Running(0)Running(0) Stopped(16)Stopped(16) StopRequested(1)StopRequested(1) Suspended(64)Suspended(64) SuspendRequested(2)SuspendRequested(2)Unstarted(8)Unstarted(8)

НеНе е стартирана, стартира се със е стартирана, стартира се със Start()Start()След като се стартира нишката никога повече След като се стартира нишката никога повече

не може пак да е в това състояниене може пак да е в това състояние WaitSleepJoin(32)WaitSleepJoin(32)

фдгдфгсдффдгдфгсдф

Състоянията в Състоянията в ThreadStateThreadState Aborted(256)Aborted(256) AbortRequested(128)AbortRequested(128) Background(4)Background(4) Running(0)Running(0) Stopped(16)Stopped(16) StopRequested(1)StopRequested(1) Suspended(64)Suspended(64) SuspendRequested(2)SuspendRequested(2) Unstarted(8)Unstarted(8)WaitSleepJoin(32)WaitSleepJoin(32)

Нишката е блокиранаНишката е блокиранаСтава с един от методитеСтава с един от методите Thread.Wait()Thread.Wait(), , Thread.Sleep()Thread.Sleep(), , Thread.Join()Thread.Join()

фдгдфгсдффдгдфгсдф

Прекратяване на нишкиПрекратяване на нишки

За да се “убие” една нишка, се използва методът За да се “убие” една нишка, се използва методът Thread.Abort()Thread.Abort()

Thread.Abort()Thread.Abort() хвърля специалното изключение хвърля специалното изключение ThreadAbortedExceptionThreadAbortedExceptionХвърля Хвърля ThreadStateExceptionThreadStateException, ако нишката вече е , ако нишката вече е

прекратенапрекратена

Изпълняват се Изпълняват се catchcatch и и finallyfinally на прекратената на прекратената нишканишка

Thread.ResetAbort()Thread.ResetAbort() не позволява на CLR да не позволява на CLR да хвърли изключението отновохвърли изключението отново

Unmanaged code – изчакванеUnmanaged code – изчакване

фдгдфгсдффдгдфгсдф

Прекратяване на нишки – примерПрекратяване на нишки – примерpublic class Backpublic class BackggroundThread {roundThread { public void public void DDoBackgroundJob() {oBackgroundJob() { trytry {{ // Нишката извършва някаква работа// Нишката извършва някаква работа }} catch(ThreadInterruptedException)catch(ThreadInterruptedException) {{ MessageBox.Show("Thread MessageBox.Show("Thread iinterruptednterrupted..");"); }} catch(ThreadAbortException) {catch(ThreadAbortException) { MessageBox.Show("ThreadMessageBox.Show("Thread aborted. aborted.");"); }} finallyfinally {{ MessageBox.Show("MessageBox.Show("FFinally blockinally block..");"); }} MessageBox.Show(MessageBox.Show("After finally block."After finally block.");"); }}}} ((примерът продължава)примерът продължава)

фдгдфгсдффдгдфгсдф

Прекратяване на нишки – примерПрекратяване на нишки – пример

public class InterruptAbortDemopublic class InterruptAbortDemo{{ private Thread mBgThread;private Thread mBgThread;

public InterruptAbortDemo() {public InterruptAbortDemo() { bg = new BackgroundThread();bg = new BackgroundThread(); mBgThread = new Thread(newmBgThread = new Thread(new ThreadStart(bg.DoBackgroundJob));ThreadStart(bg.DoBackgroundJob)); mBgThread.IsBackground = true;mBgThread.IsBackground = true; mBgThread.Start();mBgThread.Start(); }}

private void btnSuspend_Click(...)private void btnSuspend_Click(...) {{ mBgThread.Suspend();mBgThread.Suspend(); }} ((примерът продължава)примерът продължава)

фдгдфгсдффдгдфгсдф

Прекратяване на нишки – примерПрекратяване на нишки – пример

private void btnResume_Click(...)private void btnResume_Click(...) {{ mBgThread.Resume();mBgThread.Resume(); }}

private void btnInterrupt_Click(...)private void btnInterrupt_Click(...) {{ mBgThread.Interrupt();mBgThread.Interrupt(); }}

private void btnAbort_Click(...)private void btnAbort_Click(...) {{ mBgThread.Abort();mBgThread.Abort(); }}}}

фдгдфгсдффдгдфгсдф

Демонстрация #Демонстрация #66Използване на Използване на PriorityPriority, , StateState, , SuspendSuspend, , ResumeResume, , InterruptInterrupt и и AbortAbort

фдгдфгсдффдгдфгсдф

Thread Local StorageThread Local StorageКонтейнер, в който нишките могат да Контейнер, в който нишките могат да

съхраняват даннисъхраняват данниНишка не може да достъпи данните на Нишка не може да достъпи данните на

друга нишкадруга нишкаThread.AllocateNamedDataSlotThread.AllocateNamedDataSlot

Именуван контейнерИменуван контейнерПроблеми – уникални именаПроблеми – уникални имена

Thread.AllocateDataSlotThread.AllocateDataSlotНяма име, само referenceНяма име, само reference

Проблеми: две парчета код от една и Проблеми: две парчета код от една и съща нишка използват общ слотсъща нишка използват общ слот

фдгдфгсдффдгдфгсдф

ThreadThread LocalLocal StorageStorage – пример – примерclass Threads {class Threads { public void CreateDataThread() {public void CreateDataThread() { LocalDataStoreSlot slot =LocalDataStoreSlot slot = Thread.AllocateNamedDataSlot("mySlot");Thread.AllocateNamedDataSlot("mySlot");

//Записваме важни данни в NamedSlot//Записваме важни данни в NamedSlot Thread.SetData(slot ,"IMPORTANT DATA");Thread.SetData(slot ,"IMPORTANT DATA"); // Suspend-ваме// Suspend-ваме Thread.CurrentThread.Suspend();Thread.CurrentThread.Suspend(); // Прочитаме отново данните// Прочитаме отново данните object myData = Thread.GetData("mySlot");object myData = Thread.GetData("mySlot"); }}

public void ReadDataThread() {public void ReadDataThread() { LocalDataStoreSlot slot =LocalDataStoreSlot slot = Thread.GetNamedDataSlot("mySlot");Thread.GetNamedDataSlot("mySlot"); // Опитваме се да променим информацията// Опитваме се да променим информацията Thread.SetData(slot, "BAD DATA");Thread.SetData(slot, "BAD DATA"); }}}} (примерът продължава)(примерът продължава)

фдгдфгсдффдгдфгсдф

ThreadThread LocalLocal StorageStorage – пример – примерclass TLSDemoclass TLSDemo{{ static void Main(string[] args)static void Main(string[] args) {{ Threads threads = new Threads();Threads threads = new Threads(); Thread createData = new Thread( newThread createData = new Thread( new ThreadStart(threads.createDataThread) );ThreadStart(threads.createDataThread) ); createData.Start();createData.Start();

Thread readData = new Thread( newThread readData = new Thread( new ThreadStart(threads.readDataThread) );ThreadStart(threads.readDataThread) ); readData.Start();readData.Start(); readData.Join();readData.Join(); createData.Resume();createData.Resume(); }}}}

фдгдфгсдффдгдфгсдф

Демонстрация #Демонстрация #77

ThreadLocalStorageThreadLocalStorage

фдгдфгсдффдгдфгсдф

Thread-Relative Static FieldsThread-Relative Static Fields

Като статична променлива, но има по една Като статична променлива, но има по една инстанция за всяка нишка на програматаинстанция за всяка нишка на програмата

Декларира се като статична променлива, Декларира се като статична променлива, но с атрибута но с атрибута [[ThreadStaticThreadStatic]]

Всяка нишка, която я използва трябва да я Всяка нишка, която я използва трябва да я инициализираинициализира

Не разчитайте на конструктора да Не разчитайте на конструктора да инициализира такива променливи, защото инициализира такива променливи, защото той се изпълнява в родителската нишка!той се изпълнява в родителската нишка!

фдгдфгсдффдгдфгсдф

Thread-Relative Static Fields – Thread-Relative Static Fields – примерпример

class ThreadStatic {class ThreadStatic { static void Main(string[] args) {static void Main(string[] args) { for( int i=0; i<10; i++ ) {for( int i=0; i<10; i++ ) { new Thread(new ThreadStart(newnew Thread(new ThreadStart(new MyThread().MyThread().DDoTask)).Start();oTask)).Start(); }} }}}}

class MyThread {class MyThread { [ThreadStatic] public static int abc;[ThreadStatic] public static int abc; public MyThread() {public MyThread() { abc=42; abc=42; // // This runs in the main app. threadThis runs in the main app. thread }} public void public void DDoTask() {oTask() { abc++;abc++; Console.WriteLine("abc=Console.WriteLine("abc={0}{0}"", , abc);abc); }}}}

фдгдфгсдффдгдфгсдф

Демонстрация #8Демонстрация #8

Използване на Използване на ThreadThread StaticStatic поле поле

фдгдфгсдффдгдфгсдф

Неудобства на нишкитеНеудобства на нишкитеСамата имплементация на Самата имплементация на

многонишковост изисква ресурсимногонишковост изисква ресурсиДобра практика е да не прекалявате с Добра практика е да не прекалявате с

използването на нишкиизползването на нишкиВъзможно е процесорът да използва повече Възможно е процесорът да използва повече

ресурси за управлението на нишките ресурси за управлението на нишките отколкото за изпълнението имотколкото за изпълнението им

Препоръчва се да използвате Препоръчва се да използвате ThreadPoolThreadPool когато е възможнокогато е възможно

Следенето на много нишки е трудно Следенето на много нишки е трудно

фдгдфгсдффдгдфгсдф

Споделени данни –Споделени данни – проблемипроблеми

Race conditionRace conditionДве нишки едновременно достъпват едни и Две нишки едновременно достъпват едни и

същи даннисъщи данниНепредвидими резултатиНепредвидими резултатиНапример две нишки едновременно изпълняват Например две нишки едновременно изпълняват

i++ i++ на обща променлива на обща променлива ii DeadlockDeadlock

Състояние, в което две нишки се чакат взаимно Състояние, в което две нишки се чакат взаимно за освобождаване на взаимно заети ресурсиза освобождаване на взаимно заети ресурси

AA заема ресурса заема ресурса XX, , BB заема ресурса заема ресурса Y Y и чака за и чака за X,X, а а A A започва да чака за започва да чака за YY

фдгдфгсдффдгдфгсдф

Race Condition – Race Condition – примерпримерusing System;using System;using System.Threading;using System.Threading;

class Accountclass Account{{ public int mBalance;public int mBalance;

public void Withdraw100()public void Withdraw100() {{ int oldBalance = mBalance;int oldBalance = mBalance; Console.WriteLine("Withdrawing 100...");Console.WriteLine("Withdrawing 100..."); Thread.Sleep(100);Thread.Sleep(100); int newBalance = oldBalance - 100;int newBalance = oldBalance - 100; mBalance = newBalance;mBalance = newBalance; }}}} (примерът продължава)(примерът продължава)

фдгдфгсдффдгдфгсдф

Race ConditionRace Condition – пример – примерstatic void Main(string[] args)static void Main(string[] args){{ Account acc = new Account();Account acc = new Account(); acc.mBalance = 500;acc.mBalance = 500; Console.WriteLine("Console.WriteLine("Account balance = {0}Account balance = {0}"",, acc.mBalance);acc.mBalance); Thread user1 = new Thread( Thread user1 = new Thread( new ThreadStart(acc.Withdraw100) );new ThreadStart(acc.Withdraw100) ); Thread user2 = new Thread(Thread user2 = new Thread( new ThreadStart(acc.Withdraw100) );new ThreadStart(acc.Withdraw100) ); user1.Start();user1.Start(); user2.Start();user2.Start(); user1.Join();user1.Join(); user2.Join();user2.Join(); Console.WriteLine("Console.WriteLine("Account balance = {0}Account balance = {0}"",, acc.mBalance);acc.mBalance);}}

фдгдфгсдффдгдфгсдф

Демонстрация Демонстрация ##99

Повреждане на данниПовреждане на данни

фдгдфгсдффдгдфгсдф

Синхронизация – съдържаниеСинхронизация – съдържание МногозадачностМногозадачност НишкиНишки СинхронизацияСинхронизация

Най-доброто решениеНай-доброто решение ““Стратегии” за синхронизацияСтратегии” за синхронизацияSynchronized ContextsSynchronized ContextsSynchronized code regionsSynchronized code regionsMethodImplAttributeMethodImplAttributeUnmanaged Synchronization – Unmanaged Synchronization – WaitHandleWaitHandleСпециални класове Специални класове

Класически синхронизационни проблемиКласически синхронизационни проблемиThreadPoolThreadPool

Асинхронни извикванияАсинхронни извиквания

фдгдфгсдффдгдфгсдф

Най-доброто решениеНай-доброто решение

Най-добра сигурност при споделени данни в Най-добра сигурност при споделени данни в многонишкова среда е липсата на многонишкова среда е липсата на споделени даннисподелени данни

Препоръчва се Препоръчва се Да се капсулират данните и ресурсите в Да се капсулират данните и ресурсите в

инстанции на обектиинстанции на обектиТези обекти да не се споделят между нишкиТези обекти да не се споделят между нишки

Когато това е невъзможно, Когато това е невъзможно, .NET Framework, .NET Framework, предоставя механизми за синхронизация на предоставя механизми за синхронизация на достъпа до даннидостъпа до данни

фдгдфгсдффдгдфгсдф

““Стратегии” за синхронизацияСтратегии” за синхронизацияСинхронизирани контексти (Synchronized Синхронизирани контексти (Synchronized

Contexts)Contexts)Синхронизирани “пасажи” код (Synchronized Синхронизирани “пасажи” код (Synchronized

code regions)code regions)[MethodImplAttribute [MethodImplAttribute (MethodImplOptions.Synchronized)](MethodImplOptions.Synchronized)] над имплементацията на методнад имплементацията на метод

Unmanaged синхронизация Unmanaged синхронизация Класове за фина, ръчно настроена (custom) Класове за фина, ръчно настроена (custom)

синхронизация с обекти на OSсинхронизация с обекти на OS

фдгдфгсдффдгдфгсдф

Synchronized ContextsSynchronized Contexts

Използва се Използва се SynchronizationAttributeSynchronizationAttribute за за обекти, наследяващи обекти, наследяващи ContextBoundObjectContextBoundObject обекти, които оперират в един контекстобекти, които оперират в един контекст

Всички нишки в този контекст достъпват Всички нишки в този контекст достъпват методите на инстанции на такива обекти методите на инстанции на такива обекти последователнопоследователно

Статичните членове не са предпазениСтатичните членове не са предпазени Не се поддържа синхронизиране на специфични Не се поддържа синхронизиране на специфични

“отрязъци” от код – синхронизира цял клас“отрязъци” от код – синхронизира цял клас

фдгдфгсдффдгдфгсдф

Synchronized ContextsSynchronized Contexts – пример – пример[SynchronizationAttribute][SynchronizationAttribute]class CBO : ContextBoundObjectclass CBO : ContextBoundObject{{ public void DoSomeTask1()public void DoSomeTask1() {{ Console.WriteLine("Job1 started.");Console.WriteLine("Job1 started."); Thread.Sleep(2000);Thread.Sleep(2000); Console.WriteLine("Job1 finished.\n");Console.WriteLine("Job1 finished.\n"); }}

public void DoSomeTask2()public void DoSomeTask2() {{ Console.WriteLine("Job2 started.");Console.WriteLine("Job2 started."); Thread.Sleep(1500);Thread.Sleep(1500); Console.WriteLine("Job2 finished.\n");Console.WriteLine("Job2 finished.\n"); }}}} ((примерът продължава)примерът продължава)

фдгдфгсдффдгдфгсдф

Synchronized ContextsSynchronized Contexts – пример – примерstatic void Main()static void Main(){{ CBO syncClass = new CBO();CBO syncClass = new CBO(); Console.WriteLine("Started 6 threads:\n" +Console.WriteLine("Started 6 threads:\n" + "3 doing Job1 and 3 doing Job2.\n\n");"3 doing Job1 and 3 doing Job2.\n\n"); for (int i=0; i<6; i++)for (int i=0; i<6; i++) {{ Thread t;Thread t; if (i%2==0) if (i%2==0) t = new Thread( new ThreadStart(t = new Thread( new ThreadStart( syncClass.DoSomeTask1) );syncClass.DoSomeTask1) ); elseelse t = new Thread( new ThreadStart(t = new Thread( new ThreadStart( syncClass.DoSomeTask2) );syncClass.DoSomeTask2) ); t.Start();t.Start(); }}}}

фдгдфгсдффдгдфгсдф

Демонстрация #10Демонстрация #10

Синхронизация чрез Синхронизация чрез ContextBoundObjectContextBoundObject

фдгдфгсдффдгдфгсдф

Критични секцииКритични секцииlock (obj) {lock (obj) { //..code.. //..code..}}

Управлявана (managed) реализацияУправлявана (managed) реализация Може да се ползва и за статични Може да се ползва и за статични

членове на класоветечленове на класовете Синхронизира се изпълнението Синхронизира се изпълнението

само частта, която е застрашенасамо частта, която е застрашена Нарича се критична секцияНарича се критична секция

Monitor.TryEnter();Monitor.TryEnter();

Monitor.Enter(obj);Monitor.Enter(obj);try { /*..code..*/ }try { /*..code..*/ }finally { Monitor.Exit(obj); }finally { Monitor.Exit(obj); }

фдгдфгсдффдгдфгсдф

Критични секции – примерКритични секции – примерpublic class MonitorEnterExitpublic class MonitorEnterExit{{ private int mCounter;private int mCounter;

public void CriticalSection()public void CriticalSection() {{ Monitor.Enter(this);Monitor.Enter(this); mCounter = 0;mCounter = 0; trytry {{ for(int i = 1; i <= 5; i++) { for(int i = 1; i <= 5; i++) { Console.Write(++mCounter);Console.Write(++mCounter); Thread.Sleep(1000);Thread.Sleep(1000); }} }} finallyfinally {{ Monitor.Exit(this);Monitor.Exit(this); }} }} (примерът продължава)(примерът продължава)

фдгдфгсдффдгдфгсдф

Критични секции – примерКритични секции – пример sstatic void Main() { tatic void Main() { MonitorEnterExit meMonitorEnterExit meee = new MonitorEnterExit(); = new MonitorEnterExit(); Thread Thread thread1thread1 = new Thread(new = new Thread(new ThreadStart(mee.CriticalSection)); ThreadStart(mee.CriticalSection)); thread1thread1.Start( );.Start( ); Thread Thread thread2thread2 = new Thread(new = new Thread(new ThreadStart(mee.CriticalSection)); ThreadStart(mee.CriticalSection)); thread2thread2.Start( );.Start( ); }}}}

// Резултат: 1234512345// Резултат: 1234512345

// Резултат без синхронизация: 1123456789// Резултат без синхронизация: 1123456789

фдгдфгсдффдгдфгсдф

Демонстрация #1Демонстрация #111

Работа с критични секцииРабота с критични секции

фдгдфгсдффдгдфгсдф

Няколко важни методаНяколко важни методаMonitor.Wait(object)Monitor.Wait(object)

Освобождава монитора на обекта и блокира Освобождава монитора на обекта и блокира нишката докато не го получинишката докато не го получи

Може да се задава Може да се задава TimeoutTimeoutНишката се нарежда на waiting queueНишката се нарежда на waiting queueЧака Чака Pulse(object)Pulse(object), , PulseAll(object)PulseAll(object)

Monitor.Pulse(object)Monitor.Pulse(object)Нишката преминава в ready queueНишката преминава в ready queue

(има право да вземе монитора на обект)(има право да вземе монитора на обект)Вика се само от текущия собственик на Вика се само от текущия собственик на

монитора на обекта (от критична секция)монитора на обекта (от критична секция)Monitor.PulseAll(object)Monitor.PulseAll(object)

фдгдфгсдффдгдфгсдф

Wait()Wait() и и Pulse()Pulse() – – примерпример

public class WaitPulsepublic class WaitPulse{{ private object mSync;private object mSync; private string mName;private string mName;

public WaitPulse(string aName,public WaitPulse(string aName, object aSync)object aSync) {{ mName = aName;mName = aName; mSync = aSync;mSync = aSync; }} ((примерът продължава)примерът продължава)

Имаме две нишки, които съвместно Имаме две нишки, които съвместно изпълняват някаква задачаизпълняват някаква задача

Когато едната прави нещо, другата я Когато едната прави нещо, другата я изчаква и обратнотоизчаква и обратното

фдгдфгсдффдгдфгсдф

Wait()Wait() и и Pulse()Pulse() – – примерпример public void DoJob()public void DoJob() {{ lock (mSync)lock (mSync) {{ Monitor.Pulse(mSync);Monitor.Pulse(mSync); for(int i = 1; i <= for(int i = 1; i <= 33; i++); i++) {{ Console.WriteLine("{0}: Pulsе", mName);Console.WriteLine("{0}: Pulsе", mName); Monitor.Pulse(mSync);Monitor.Pulse(mSync);

Console.WriteLine("{0}: Wait", mName);Console.WriteLine("{0}: Wait", mName); Monitor.Wait(mSync);Monitor.Wait(mSync);

Console.WriteLine("{0}: WokeUp", mName);Console.WriteLine("{0}: WokeUp", mName); Thread.Sleep(1000);Thread.Sleep(1000); }} }} }}}} ((примерът продължава)примерът продължава)

фдгдфгсдффдгдфгсдф

Wait()Wait() и и Pulse()Pulse() – – примерпримерpublic class WaitPulseDemopublic class WaitPulseDemo{{ public static void Main(String[] args)public static void Main(String[] args) {{ object sync = new object();object sync = new object();

WaitPulse wp1 = new WaitPulse(WaitPulse wp1 = new WaitPulse( "WaitPulse1", sync);"WaitPulse1", sync); Thread thread1 = new Thread(Thread thread1 = new Thread( new ThreadStart(wp1.DoJob));new ThreadStart(wp1.DoJob)); thread1.Start();thread1.Start();

WaitPulse wp2 = new WaitPulse(WaitPulse wp2 = new WaitPulse( "WaitPulse2", sync);"WaitPulse2", sync); Thread thread2 = new Thread(Thread thread2 = new Thread( new ThreadStart(wp2.DoJob));new ThreadStart(wp2.DoJob)); thread2.Start();thread2.Start(); }}}}

фдгдфгсдффдгдфгсдф

Демонстрация #12Демонстрация #12

Работа с Работа с Wait()Wait() и и Pulse()Pulse()

фдгдфгсдффдгдфгсдф

Прилича на Прилича на locklock върху цял метод върху цял метод Може да синхронизира и Може да синхронизира и static static членовечленове

[MethodImplAttribute [MethodImplAttribute (MethodImplOptions.Synchronized)](MethodImplOptions.Synchronized)]

[MethodImpl(MethodImplOptions.Synchronized)][MethodImpl(MethodImplOptions.Synchronized)] public void public void DDoSomeTask1()oSomeTask1(){{ Console.WriteLine("job1 started");Console.WriteLine("job1 started"); forfor (int i=0; i<1(int i=0; i<10000000000; i++)00000000; i++) Math.Sqrt(i);Math.Sqrt(i); Console.WriteLine("Console.WriteLine("JJob1 doneob1 done..\n");\n");}}

фдгдфгсдффдгдфгсдф

Unmanaged SynchronizationUnmanaged Synchronization

WaitHandleWaitHandleUnmanaged механизъм за синхронизацияUnmanaged механизъм за синхронизацияИзползва обекти на операционната система – Използва обекти на операционната система –

за изчакване на ресурсиза изчакване на ресурсиПредоставя възможности отвъд тези на CLR – Предоставя възможности отвъд тези на CLR – WaitAll()WaitAll(), , WaitAny()WaitAny()

Не се препоръчва – не е managedНе се препоръчва – не е managed Има няколко наследника:Има няколко наследника:

MutexMutexAutoResetEventAutoResetEventManualResetEventManualResetEvent

фдгдфгсдффдгдфгсдф

Класът Класът WaitHandleWaitHandle

Неговите методи се използват за изчакване на Неговите методи се използват за изчакване на събитиясъбития

Състояния: signaled, nonsignaledСъстояния: signaled, nonsignaled WaitAll() (static)WaitAll() (static)

Изчаква сигнал от всички събития от масивИзчаква сигнал от всички събития от масив WaitAny() (static)WaitAny() (static)

Изчаква първото получило сигналИзчаква първото получило сигнал WaitOne()WaitOne()

Изчаква текущото събитие да приключиИзчаква текущото събитие да приключи Прилики и разлики с класаПрилики и разлики с класа Monitor Monitor

фдгдфгсдффдгдфгсдф

MutexMutex

Наследник на Наследник на WaitHandleWaitHandle Примитив за синхронизация на OSПримитив за синхронизация на OS Енкапсулира Win32 synchronization handlesЕнкапсулира Win32 synchronization handlesMutex.WaitOne();Mutex.WaitOne();Mutex.ReleaseMutex();Mutex.ReleaseMutex();

Трябва да се извика, същия брой пъти като Трябва да се извика, същия брой пъти като Mutex.WaitOne();Mutex.WaitOne();

WaitHandle.WaitAll()WaitHandle.WaitAll() – изчаква два или – изчаква два или няколко handle-aняколко handle-a

фдгдфгсдффдгдфгсдф

MutexMutex – пример – примерclass MutexDemoclass MutexDemo{{ Mutex mMutex;Mutex mMutex; public MutexDemo(Mutex aMutex)public MutexDemo(Mutex aMutex) {{ mMutex = aMutex;mMutex = aMutex; }} public void PerformSomeTask()public void PerformSomeTask() {{ m.WaitOne();m.WaitOne(); Console.WriteLine("\nJob started...");Console.WriteLine("\nJob started..."); for( int i=0; i<10; i++)for( int i=0; i<10; i++) {{ Thread.Sleep(100);Thread.Sleep(100); Console.Write("|");Console.Write("|"); }} Console.WriteLine("\nJob finished.");Console.WriteLine("\nJob finished."); m.ReleaseMutex();m.ReleaseMutex(); }}}}

фдгдфгсдффдгдфгсдф

Демонстрация #13Демонстрация #13

Синхронизация с Синхронизация с MutexMutex

фдгдфгсдффдгдфгсдф

AutoResetEventAutoResetEvent,,ManualResetEventManualResetEvent

Наследници на Наследници на WaitHandleWaitHandle Примитиви за синхронизацияПримитиви за синхронизация Енкапсулират Win32 synchronization handlesЕнкапсулират Win32 synchronization handles Сигнализиране със Сигнализиране със Set()Set()

AutoResetEventAutoResetEvent сигнализира само първия сигнализира само първия манипулатор(handle)манипулатор(handle)Минава автоматично в nonsignaled stateМинава автоматично в nonsignaled state

ManualResetEvent()ManualResetEvent() сигнализира всички сигнализира всички чакащи манипулаторичакащи манипулаториОстава в signaled state, докато някой не го Остава в signaled state, докато някой не го

променипромени

фдгдфгсдффдгдфгсдф

AutoResetEvent/AutoResetEvent/ManualResetEventManualResetEvent

using System;using System;using System.Threading;using System.Threading;class OneWhoWaitsclass OneWhoWaits{{ WaitHandle mWaitHandle;WaitHandle mWaitHandle; int mWaitTime;int mWaitTime; public OneWhoWaits(WaitHandle aWaitHandle,public OneWhoWaits(WaitHandle aWaitHandle, int waitTime )int waitTime ) {{ mWaitHandle = aWaitHandle;mWaitHandle = aWaitHandle; mWaitTime = mWaitTime;mWaitTime = mWaitTime; }} public void performSomeTask()public void performSomeTask() {{ Thread.Sleep(mWaitTime);Thread.Sleep(mWaitTime); Console.WriteLine("Thread {0} waiting",Console.WriteLine("Thread {0} waiting", Thread.CurrentThread.GetHashCode());Thread.CurrentThread.GetHashCode()); mWaitHandle.WaitOne();mWaitHandle.WaitOne(); }}}} (примерът продължава)(примерът продължава)

фдгдфгсдффдгдфгсдф

AutoResetEvent/AutoResetEvent/ManualResetEventManualResetEvent

class MainClassclass MainClass{{ static void Main()static void Main() {{ ManualResetEvent evnt = newManualResetEvent evnt = new ManualResetEvent(false);ManualResetEvent(false); for (int i=0; i<10; i++ )for (int i=0; i<10; i++ ) {{ OneWhoWaits oww = OneWhoWaits oww = new OneWhoWaits(evnt, (i+1)*500);new OneWhoWaits(evnt, (i+1)*500); Thread thread = new Thread(Thread thread = new Thread( new ThreadStart(oww.performSomeTask));new ThreadStart(oww.performSomeTask)); thread.Start();thread.Start(); }} for (int i=0; i<10; i++)for (int i=0; i<10; i++) {{ Console.ReadLine();Console.ReadLine(); evnt.Set();evnt.Set(); }} }}}}

фдгдфгсдффдгдфгсдф

Демонстрация #14Демонстрация #14

Синхронизация с Синхронизация с AutoResetEventAutoResetEvent и и ManualResetEventManualResetEvent

фдгдфгсдффдгдфгсдф

Специални класовеСпециални класове

System.Threading.InterlockedSystem.Threading.InterlockedАтомарни операцииАтомарни операции

System.Threading.ThreadPoolSystem.Threading.ThreadPoolБърз достъп до нишкиБърз достъп до нишкиПреизползваемост на нишкитеПреизползваемост на нишкитеПрограмистът не се грижи за живота на Програмистът не се грижи за живота на

нишкитенишките ( (създаване / унищожаване)създаване / унищожаване) System.Threading.ReaderWriterLockSystem.Threading.ReaderWriterLock

Класически синхронизационни проблеми – Класически синхронизационни проблеми – Reader/Writer ProblemReader/Writer Problem

Synchronized WrappersSynchronized Wrappers

фдгдфгсдффдгдфгсдф

System.Threading.InterlockedSystem.Threading.Interlocked

Осигурява изпълнение на атомарни операции Осигурява изпълнение на атомарни операции

– увеличение с 1, намаление с 1, размяна, – увеличение с 1, намаление с 1, размяна,

сравнение и др.сравнение и др.

Няма нужда синхронизация на споделените Няма нужда синхронизация на споделените

данниданни

В по-простите случаи синхронизацията може В по-простите случаи синхронизацията може

да се избегне с тези методида се избегне с тези методи

Методите не хвърлят изключенияМетодите не хвърлят изключения

фдгдфгсдффдгдфгсдф

System.Threading.InterlockedSystem.Threading.Interlocked

Increment/DecrementIncrement/DecrementАтомарна операция за разлика от Атомарна операция за разлика от i++/i--i++/i--

ExchangeExchangeЗаписва стойността на вторият параметър Записва стойността на вторият параметър

в първия, връща оригиналав първия, връща оригиналаCompareExchangeCompareExchange

Има три параметъраИма три параметъраПроверява дали първият и третият са Проверява дали първият и третият са

равни, ако да, записва втория в първияравни, ако да, записва втория в първияИзползва се при работа с временни Използва се при работа с временни

променливипроменливи

фдгдфгсдффдгдфгсдф

InterlockedInterlocked – пример – примерclass TestInterlockedIncrementclass TestInterlockedIncrement{{ static long mUnsafeCounter = 0;static long mUnsafeCounter = 0; static long mSafeCounter = 0;static long mSafeCounter = 0;

private static void DoTask()private static void DoTask() {{ while (true)while (true) {{ mUnsafeCounter++;mUnsafeCounter++; Interlocked.Increment(ref mSafeCounter);Interlocked.Increment(ref mSafeCounter);

if (mSafeCounter % 10000000 == 0)if (mSafeCounter % 10000000 == 0) {{ Console.WriteLine("Safe={0}, Unsafe={1}",Console.WriteLine("Safe={0}, Unsafe={1}", mSafeCounter, mUnsafeCounter);mSafeCounter, mUnsafeCounter); }} }} }}

фдгдфгсдффдгдфгсдф

static void Main(string[] args)static void Main(string[] args) {{ for (int i=0; i<for (int i=0; i<55; i++); i++) {{ Thread thread = new Thread(Thread thread = new Thread( new ThreadStart(DoTask));new ThreadStart(DoTask)); thread.Start();thread.Start(); }} }}}}

// // Резултат:Резултат:// Safe=10000000, Unsafe=5846325// Safe=10000000, Unsafe=5846325// Safe=20000000, Unsafe=15846326// Safe=20000000, Unsafe=15846326// Safe=30000000, Unsafe=25846326// Safe=30000000, Unsafe=25846326// Safe=40000000, Unsafe=35846325// Safe=40000000, Unsafe=35846325// Safe=50000000, Unsafe=41356463// Safe=50000000, Unsafe=41356463// ...// ...

InterlockedInterlocked – пример – пример

фдгдфгсдффдгдфгсдф

Thread PoolingThread PoolingМного нишки прекарват по-голямата част Много нишки прекарват по-голямата част

от живота си спейки от живота си спейки ((ThreadState.WaitSleepJoinThreadState.WaitSleepJoin) ) или или чакайки някакво събитиечакайки някакво събитие

Други се “събуждат” само за малки Други се “събуждат” само за малки периоди, за да проверят истинността на периоди, за да проверят истинността на някакво условие или за да свършат нещо някакво условие или за да свършат нещо дребнодребно

Поддържането на много неактивни нишки Поддържането на много неактивни нишки е излишно, неефективно и консумира е излишно, неефективно и консумира ресурсиресурси

фдгдфгсдффдгдфгсдф

ThreadThread PoolingPooling TP TP е подход за намаляване на товара при е подход за намаляване на товара при

създаване и унищожаване на нишкисъздаване и унищожаване на нишки При При TP TP се създават група нишки в началото на се създават група нишки в началото на

многонишково приложениемногонишково приложение Наричат се “работни нишки” (Наричат се “работни нишки” (worker threads)worker threads) Всяка нишка “живее” в т.нар. Всяка нишка “живее” в т.нар. Thread PoolThread Pool При нова задача, се използва При нова задача, се използва worker threadworker thread, ,

след това се връща обратно в пуласлед това се връща обратно в пула TP TP се грижи за живота и разпределението на се грижи за живота и разпределението на

задачите върху нишкитезадачите върху нишките Използващият нишки се освобождава от този Използващият нишки се освобождава от този

товартовар

фдгдфгсдффдгдфгсдф

System.Threading.ThreadPooSystem.Threading.ThreadPooll .NET Framework имплементира механизма .NET Framework имплементира механизма

Thread Pooling в класа Thread Pooling в класа ThreadPoolThreadPool Използва се, когато трябва да се свършат Използва се, когато трябва да се свършат

много на брой кратки задачи, които могат да много на брой кратки задачи, които могат да работят паралелноработят паралелно

Задачите се нареждат на опашка и се Задачите се нареждат на опашка и се изпълняват по няколко едновременно (според изпълняват по няколко едновременно (според броя worker threads)броя worker threads)

По подразбиране в Thread Pool-ът има лимит от По подразбиране в Thread Pool-ът има лимит от 25 нишки на процесор25 нишки на процесор

Един процес може да има само един Thread Един процес може да има само един Thread Pool – той е общ за всички App DomainsPool – той е общ за всички App Domains

фдгдфгсдффдгдфгсдф

System.Threading.ThreadPooSystem.Threading.ThreadPooll Thread PoolThread Pool-ът за даден процес се създава се при -ът за даден процес се създава се при

първото:първото: извикване на извикване на QueueUserWorkItemQueueUserWorkItem регистриране на таймер регистриране на таймер регистриране на изчакващарегистриране на изчакваща операция с операция с callbackcallback

методметод .NET Framework .NET Framework използва използва Thread Pooling Thread Pooling заза::

асинхронни извикванияасинхронни извиквания асинхронен вход/изходасинхронен вход/изход работа с таймериработа с таймери работа със сокетиработа със сокети изчакващи операцииизчакващи операции

фдгдфгсдффдгдфгсдф

System.Threading.ThreadPooSystem.Threading.ThreadPooll Ако дадена задача е в Ако дадена задача е в ThreadThread PoolPool, не може , не може

да се премахне от негода се премахне от него ThreadThread Pooling Pooling позволява на позволява на OS OS да да

оптимизира използването на нишки, тъй оптимизира използването на нишки, тъй като броят им е постояненкато броят им е постоянен

Случаи, в които НЕ се препоръчва Случаи, в които НЕ се препоръчва използването на използването на ThreadThread PoolPoolАко е нужна контролираща нишкаАко е нужна контролираща нишкаПри задачи, отнемащи много време – може да При задачи, отнемащи много време – може да

се блокират другите задачисе блокират другите задачиАко има нужда от синхронизацияАко има нужда от синхронизация

фдгдфгсдффдгдфгсдф

ThreadPool.QueueUserWorkItemThreadPool.QueueUserWorkItemclass ThreadPoolDemoclass ThreadPoolDemo{{ public static void LongTask(object aParam)public static void LongTask(object aParam) {{ Console.WriteLine("Started: {0}.", aParam);Console.WriteLine("Started: {0}.", aParam); Thread.Sleep(500);Thread.Sleep(500); Console.WriteLine("Finished: {0}.", aParam);Console.WriteLine("Finished: {0}.", aParam); }}

static void Main()static void Main() {{ for (int i=1; i<=100; i++)for (int i=1; i<=100; i++) {{ string taskName = "Task" + i;string taskName = "Task" + i; ThreadPool.QueueUserWorkItem(newThreadPool.QueueUserWorkItem(new WaitCallback(LongTask), taskName);WaitCallback(LongTask), taskName); }}

Console.ReadLine();Console.ReadLine(); }}}}

фдгдфгсдффдгдфгсдф

Демонстрация #15Демонстрация #15

Изпълнение на задачи с Изпълнение на задачи с Thread PoolThread Pool

фдгдфгсдффдгдфгсдф

ThreadPool.RegisterWaiThreadPool.RegisterWaitForSingleObjecttForSingleObject

Регистрира делегат, който чака за Регистрира делегат, който чака за събитие (да бъде сигнализиран)събитие (да бъде сигнализиран)

Активира се при:Активира се при:сигнализиранесигнализиранепри настъпване на зададен при настъпване на зададен timeouttimeout

Процесът по изчакване и извикване се Процесът по изчакване и извикване се управлява се от управлява се от Thread PoolThread Pool-а-а

Може да настрои да се изпълнява Може да настрои да се изпълнява делегатът многократноделегатът многократно

фдгдфгсдффдгдфгсдф

ThreadPool.RegisterWaitForSingleObjectThreadPool.RegisterWaitForSingleObjectusing ...using ...public class Example {public class Example { public static void Main(string[] args) {public static void Main(string[] args) { AutoResetEvent ev =new AutoResetEvent(false);AutoResetEvent ev =new AutoResetEvent(false); object param = "some param";object param = "some param"; RegisteredWaitHandle r =RegisteredWaitHandle r = ThreadPool.RegisterWaitForSingleObject(ThreadPool.RegisterWaitForSingleObject( ev, new WaitOrTimerCallback(WaitProc),ev, new WaitOrTimerCallback(WaitProc), param, 1000, false );param, 1000, false ); Console.ReadLine();Console.ReadLine(); Console.WriteLine("signaling.");Console.WriteLine("signaling."); ev.Set();ev.Set(); Console.ReadLine();Console.ReadLine(); Console.WriteLine("unregister wait");Console.WriteLine("unregister wait"); r.Unregister(ev);r.Unregister(ev); Console.ReadLine();Console.ReadLine(); }} public static void WaitProc(object param, bool public static void WaitProc(object param, bool timedOut) {timedOut) { string cause = "SIGNALED";string cause = "SIGNALED"; if (timedOut)if (timedOut) cause = "TIMED OUT";cause = "TIMED OUT"; Console.WriteLine("WaitProc executes;cause =Console.WriteLine("WaitProc executes;cause = {0}", cause);{0}", cause); }}}}

фдгдфгсдффдгдфгсдф

ThreadPool.RegisterWaitForSingleObjectThreadPool.RegisterWaitForSingleObjectusing ...using ...public class Example {public class Example { public static void Main(string[] args) {public static void Main(string[] args) { AutoResetEvent ev =new AutoResetEvent(false);AutoResetEvent ev =new AutoResetEvent(false); object param = "some param";object param = "some param"; RegisteredWaitHandle r =RegisteredWaitHandle r = ThreadPool.RegisterWaitForSingleObject(ThreadPool.RegisterWaitForSingleObject( ev, ev, new WaitOrTimerCallback(WaitProc)new WaitOrTimerCallback(WaitProc),, param, 1000, false );param, 1000, false ); Console.ReadLine();Console.ReadLine(); Console.WriteLine("signaling.");Console.WriteLine("signaling."); ev.Set();ev.Set(); Console.ReadLine();Console.ReadLine(); Console.WriteLine("unregister wait");Console.WriteLine("unregister wait"); r.Unregister(ev);r.Unregister(ev); Console.ReadLine();Console.ReadLine(); }} public static public static void WaitProc(object param, bool void WaitProc(object param, bool timedOut)timedOut) { { string cause = "SIGNALED";string cause = "SIGNALED"; if (timedOut)if (timedOut) cause = "TIMED OUT";cause = "TIMED OUT"; Console.WriteLine("WaitProc executes;cause =Console.WriteLine("WaitProc executes;cause = {0}", cause);{0}", cause); }}}}

фдгдфгсдффдгдфгсдф

ThreadPool.RegisterWaitForSingleObjectThreadPool.RegisterWaitForSingleObjectusing ...using ...public class Example {public class Example { public static void Main(string[] args) {public static void Main(string[] args) { AutoResetEvent evAutoResetEvent ev =new=new A AutoResetEvent(false);utoResetEvent(false); object param = "some param";object param = "some param"; RegisteredWaitHandle r =RegisteredWaitHandle r = ThreadPool.RegisterWaitForSingleObject(ThreadPool.RegisterWaitForSingleObject( ev,ev, new WaitOrTimerCallback(WaitProc),new WaitOrTimerCallback(WaitProc), param, 1000, false param, 1000, false );); Console.ReadLine();Console.ReadLine(); Console.WriteLine("signaConsole.WriteLine("signalingling.");."); ev.Set();ev.Set(); Console.ReadLine();Console.ReadLine(); Console.WriteLine("Console.WriteLine("unregister waitunregister wait");"); r.Unregister(ev);r.Unregister(ev); Console.ReadLine();Console.ReadLine(); }} public static void WaitProc(object public static void WaitProc(object paramparam, bool , bool timedOut) {timedOut) { string cause = "SIGNALED";string cause = "SIGNALED"; if (timedOut)if (timedOut) cause = "TIMED OUT";cause = "TIMED OUT"; Console.WriteLine("WaitProc executes;cause =Console.WriteLine("WaitProc executes;cause = {0}", cause);{0}", cause); }}}}

фдгдфгсдффдгдфгсдф

ThreadPool.RegisterWaitForSingleObjectThreadPool.RegisterWaitForSingleObjectusing ...using ...public class Example {public class Example { public static void Main(string[] args) {public static void Main(string[] args) { AutoResetEvent evAutoResetEvent ev =new=new A AutoResetEvent(false);utoResetEvent(false); object param = "some param";object param = "some param"; RegisteredWaitHandle r =RegisteredWaitHandle r = ThreadPool.RegisterWaitForSingleObject(ThreadPool.RegisterWaitForSingleObject( evev,, new WaitOrTimerCallback(WaitProc),new WaitOrTimerCallback(WaitProc), param, 1000, false );param, 1000, false ); Console.ReadLine();Console.ReadLine(); Console.WriteLine("signaConsole.WriteLine("signalingling.");."); ev.Set();ev.Set(); Console.ReadLine();Console.ReadLine(); Console.WriteLine("Console.WriteLine("unregister waitunregister wait");"); r.Unregister(ev);r.Unregister(ev); Console.ReadLine();Console.ReadLine(); }} public static void WaitProc(object public static void WaitProc(object paramparam, bool , bool timedOut) {timedOut) { string cause = "SIGNALED";string cause = "SIGNALED"; if (timedOut)if (timedOut) cause = "TIMED OUT";cause = "TIMED OUT"; Console.WriteLine("WaitProc executes;cause =Console.WriteLine("WaitProc executes;cause = {0}", cause);{0}", cause); }}}}

фдгдфгсдффдгдфгсдф

ThreadPool.RegisterWaitForSingleObjectThreadPool.RegisterWaitForSingleObjectusing ...using ...public class Example {public class Example { public static void Main(string[] args) {public static void Main(string[] args) { AutoResetEvent evAutoResetEvent ev =new=new A AutoResetEvent(false);utoResetEvent(false); object param = "some param";object param = "some param"; RegisteredWaitHandle r =RegisteredWaitHandle r = ThreadPool.RegisterWaitForSingleObject(ThreadPool.RegisterWaitForSingleObject( ev,ev, new WaitOrTimerCallback(WaitProc)new WaitOrTimerCallback(WaitProc),, param, 1000, false );param, 1000, false ); Console.ReadLine();Console.ReadLine(); Console.WriteLine("signaConsole.WriteLine("signalingling.");."); ev.Set();ev.Set(); Console.ReadLine();Console.ReadLine(); Console.WriteLine("Console.WriteLine("unregister waitunregister wait");"); r.Unregister(ev);r.Unregister(ev); Console.ReadLine();Console.ReadLine(); }} public static void WaitProc(object public static void WaitProc(object paramparam, bool , bool timedOut) {timedOut) { string cause = "SIGNALED";string cause = "SIGNALED"; if (timedOut)if (timedOut) cause = "TIMED OUT";cause = "TIMED OUT"; Console.WriteLine("WaitProc executes;cause =Console.WriteLine("WaitProc executes;cause = {0}", cause);{0}", cause); }}}}

фдгдфгсдффдгдфгсдф

ThreadPool.RegisterWaitForSingleObjectThreadPool.RegisterWaitForSingleObjectusing ...using ...public class Example {public class Example { public static void Main(string[] args) {public static void Main(string[] args) { AutoResetEvent evAutoResetEvent ev =new=new A AutoResetEvent(false);utoResetEvent(false); object param = "some param";object param = "some param"; RegisteredWaitHandle r =RegisteredWaitHandle r = ThreadPool.RegisterWaitForSingleObject(ThreadPool.RegisterWaitForSingleObject( ev,ev, new WaitOrTimerCallback(WaitProc),new WaitOrTimerCallback(WaitProc), paramparam, 1000, false );, 1000, false ); Console.ReadLine();Console.ReadLine(); Console.WriteLine("signaConsole.WriteLine("signalingling.");."); ev.Set();ev.Set(); Console.ReadLine();Console.ReadLine(); Console.WriteLine("Console.WriteLine("unregister waitunregister wait");"); r.Unregister(ev);r.Unregister(ev); Console.ReadLine();Console.ReadLine(); }} public static void WaitProc(public static void WaitProc(object object paramparam, bool , bool timedOut) {timedOut) { string cause = "SIGNALED";string cause = "SIGNALED"; if (timedOut)if (timedOut) cause = "TIMED OUT";cause = "TIMED OUT"; Console.WriteLine("WaitProc executes;cause =Console.WriteLine("WaitProc executes;cause = {0}", cause);{0}", cause); }}}}

фдгдфгсдффдгдфгсдф

ThreadPool.RegisterWaitForSingleObjectThreadPool.RegisterWaitForSingleObjectusing ...using ...public class Example {public class Example { public static void Main(string[] args) {public static void Main(string[] args) { AutoResetEvent evAutoResetEvent ev =new=new A AutoResetEvent(false);utoResetEvent(false); object param = "some param";object param = "some param"; RegisteredWaitHandle r =RegisteredWaitHandle r = ThreadPool.RegisterWaitForSingleObject(ThreadPool.RegisterWaitForSingleObject( ev,ev, new WaitOrTimerCallback(WaitProc),new WaitOrTimerCallback(WaitProc), param, param, 10001000, false );, false ); Console.ReadLine();Console.ReadLine(); Console.WriteLine("signaConsole.WriteLine("signalingling.");."); ev.Set();ev.Set(); Console.ReadLine();Console.ReadLine(); Console.WriteLine("Console.WriteLine("unregister waitunregister wait");"); r.Unregister(ev);r.Unregister(ev); Console.ReadLine();Console.ReadLine(); }} public static void WaitProc(object public static void WaitProc(object paramparam, bool , bool timedOut) {timedOut) { string cause = "SIGNALED";string cause = "SIGNALED"; if (timedOut)if (timedOut) cause = "TIMED OUT";cause = "TIMED OUT"; Console.WriteLine("WaitProc executes;cause =Console.WriteLine("WaitProc executes;cause = {0}", cause);{0}", cause); }}}}

фдгдфгсдффдгдфгсдф

ThreadPool.RegisterWaitForSingleObjectThreadPool.RegisterWaitForSingleObjectusing ...using ...public class Example {public class Example { public static void Main(string[] args) {public static void Main(string[] args) { AutoResetEvent evAutoResetEvent ev =new=new A AutoResetEvent(false);utoResetEvent(false); object param = "some param";object param = "some param"; RegisteredWaitHandle r =RegisteredWaitHandle r = ThreadPool.RegisterWaitForSingleObject(ThreadPool.RegisterWaitForSingleObject( ev,ev, new WaitOrTimerCallback(WaitProc),new WaitOrTimerCallback(WaitProc), param, 1000, param, 1000, falsefalse ); ); Console.ReadLine();Console.ReadLine(); Console.WriteLine("signaConsole.WriteLine("signalingling.");."); ev.Set();ev.Set(); Console.ReadLine();Console.ReadLine(); Console.WriteLine("Console.WriteLine("unregister waitunregister wait");"); r.Unregister(ev);r.Unregister(ev); Console.ReadLine();Console.ReadLine(); }} public static void WaitProc(object public static void WaitProc(object paramparam, bool , bool timedOut) {timedOut) { string cause = "SIGNALED";string cause = "SIGNALED"; if (timedOut)if (timedOut) cause = "TIMED OUT";cause = "TIMED OUT"; Console.WriteLine("WaitProc executes;cause =Console.WriteLine("WaitProc executes;cause = {0}", cause);{0}", cause); }}}}

фдгдфгсдффдгдфгсдф

ThreadPool.RegisterWaitForSingleObjectThreadPool.RegisterWaitForSingleObjectusing ...using ...public class Example {public class Example { public static void Main(string[] args) {public static void Main(string[] args) { AutoResetEvent evAutoResetEvent ev =new=new A AutoResetEvent(false);utoResetEvent(false); object param = "some param";object param = "some param"; RegisteredWaitHandle rRegisteredWaitHandle r = = ThreadPool.RegisterWaitForSingleObject(ThreadPool.RegisterWaitForSingleObject( ev,ev, new WaitOrTimerCallback(WaitProc),new WaitOrTimerCallback(WaitProc), param, 1000, false );param, 1000, false ); Console.ReadLine();Console.ReadLine(); Console.WriteLine("signaConsole.WriteLine("signalingling.");."); ev.Set();ev.Set(); Console.ReadLine();Console.ReadLine(); Console.WriteLine("Console.WriteLine("unregister waitunregister wait");"); r.Unregister(ev);r.Unregister(ev); Console.ReadLine();Console.ReadLine(); }} public static void WaitProc(object public static void WaitProc(object paramparam, bool , bool timedOut) {timedOut) { string cause = "SIGNALED";string cause = "SIGNALED"; if (timedOut)if (timedOut) cause = "TIMED OUT";cause = "TIMED OUT"; Console.WriteLine("WaitProc executes;cause =Console.WriteLine("WaitProc executes;cause = {0}", cause);{0}", cause); }}}}

фдгдфгсдффдгдфгсдф

ThreadPool.RegisterWaitForSingleObjectThreadPool.RegisterWaitForSingleObjectusing ...using ...public class Example {public class Example { public static void Main(string[] args) {public static void Main(string[] args) { AutoResetEvent evAutoResetEvent ev =new=new A AutoResetEvent(false);utoResetEvent(false); object param = "some param";object param = "some param"; RegisteredWaitHandle r =RegisteredWaitHandle r = ThreadPool.RegisterWaitForSingleObject(ThreadPool.RegisterWaitForSingleObject( ev,ev, new WaitOrTimerCallback(WaitProc),new WaitOrTimerCallback(WaitProc), param, 1000, false );param, 1000, false ); Console.ReadLine();Console.ReadLine(); Console.WriteLine("signaConsole.WriteLine("signalingling.");."); ev.Set();ev.Set(); Console.ReadLine();Console.ReadLine(); Console.WriteLine("Console.WriteLine("unregister waitunregister wait");"); r.Unregister(ev);r.Unregister(ev); Console.ReadLine();Console.ReadLine(); }} public static void WaitProc(object public static void WaitProc(object paramparam, , bool bool timedOuttimedOut) {) { string cause = "SIGNALED";string cause = "SIGNALED"; if (timedOut)if (timedOut) cause = "TIMED OUT";cause = "TIMED OUT"; Console.WriteLine("WaitProc executes;cause =Console.WriteLine("WaitProc executes;cause = {0}", cause);{0}", cause); }}}}

фдгдфгсдффдгдфгсдф

ThreadPool.RegisterWaitForSingleObjectThreadPool.RegisterWaitForSingleObjectusing ...using ...public class Example {public class Example { public static void Main(string[] args) {public static void Main(string[] args) { AutoResetEvent evAutoResetEvent ev =new=new A AutoResetEvent(false);utoResetEvent(false); object param = "some param";object param = "some param"; RegisteredWaitHandle r =RegisteredWaitHandle r = ThreadPool.RegisterWaitForSingleObject(ThreadPool.RegisterWaitForSingleObject( ev,ev, new WaitOrTimerCallback(WaitProc),new WaitOrTimerCallback(WaitProc), param, 1000, false );param, 1000, false ); Console.ReadLine();Console.ReadLine(); Console.WriteLine("signaConsole.WriteLine("signalingling.");."); ev.Set();ev.Set(); Console.ReadLine();Console.ReadLine(); Console.WriteLine("Console.WriteLine("unregister waitunregister wait");"); r.Unregister(ev);r.Unregister(ev); Console.ReadLine();Console.ReadLine(); }} public static void WaitProc(object public static void WaitProc(object paramparam, bool , bool timedOut) {timedOut) { string cause = "SIGNALED";string cause = "SIGNALED"; if (timedOut)if (timedOut) cause = "TIMED OUT";cause = "TIMED OUT"; Console.WriteLine("WaitProc executes;cause =Console.WriteLine("WaitProc executes;cause = {0}", cause);{0}", cause); }}}}

фдгдфгсдффдгдфгсдф

Демонстрация #16Демонстрация #16

RegisterWaitForSingleObjectRegisterWaitForSingleObject

фдгдфгсдффдгдфгсдф

Класически синхр. проблемиКласически синхр. проблемиThe Producer-Consumer ProblemThe Producer-Consumer Problem

Един консуматор и един производител Един консуматор и един производител споделят общсподелят общa a опашка (опашка (shared queue)shared queue)

Изисквания:Изисквания:Ако опашката е празна, консуматорът блокира Ако опашката е празна, консуматорът блокира

докато се появи нещо в неядокато се появи нещо в неяАко опашката е пълна, производителят блокира Ако опашката е пълна, производителят блокира

докато не се опразни мястодокато не се опразни мястоПроизводителят и консуматорът не могат да Производителят и консуматорът не могат да

достъпват опашката едновременнодостъпват опашката едновременноПример: пощенска кутияПример: пощенска кутияНарича се още Нарича се още bounded buffer problembounded buffer problem

Няма стандартен клас в .Няма стандартен клас в .NETNET

фдгдфгсдффдгдфгсдф

The Readers-Writers ProblemThe Readers-Writers ProblemЕдин или повече четеца и един или повече Един или повече четеца и един или повече

писеца достъпват общ ресурсписеца достъпват общ ресурсПример: достъп до общ файл в OSПример: достъп до общ файл в OSУсловия на Бернщайн:Условия на Бернщайн:

Няколко четци могат да достъпват общия ресурсНяколко четци могат да достъпват общия ресурсКогато писец достъпва ресурса, нито четец нито Когато писец достъпва ресурса, нито четец нито

друг писец може да го достъпвадруг писец може да го достъпваОчаква се нито един писец/четец да не чака Очаква се нито един писец/четец да не чака

безкрайно дълго за споделения ресурсбезкрайно дълго за споделения ресурс

В .NET – В .NET – ReaderWriterLockReaderWriterLock

Класически синхр. проблемиКласически синхр. проблеми

фдгдфгсдффдгдфгсдф

System.Threading.ReaderWriterLockSystem.Threading.ReaderWriterLock

Имплементира най-популярния Имплементира най-популярния синхронизационен проблем – синхронизационен проблем – Reader/Writer ProblemReader/Writer Problem

IsReaderLockHeldIsReaderLockHeldIsWriterLockHeldIsWriterLockHeldAcquireReaderLockAcquireReaderLockAcquireWriterLockAcquireWriterLockReleaseReaderLockReleaseReaderLockReleaseWriterLockReleaseWriterLock

фдгдфгсдффдгдфгсдф

System.Threading.ReaderWriterLockSystem.Threading.ReaderWriterLockclass Resource {class Resource { ReaderWriterLock rwl = new ReaderWriterLock();ReaderWriterLock rwl = new ReaderWriterLock(); public void Read() {public void Read() { rwl.AcquireReaderLock(Timeout.Infinite);rwl.AcquireReaderLock(Timeout.Infinite); try {try { // // MMany can read, writers any can read, writers are are blockedblocked }} finally {finally { rwl.ReleaseReaderLock();rwl.ReleaseReaderLock(); }} }} public void Write() {public void Write() { rwl.AcquireWriterLock(Timeout.Infinite);rwl.AcquireWriterLock(Timeout.Infinite); try {try { // // OOne can write, ne can write, rreaders blockedeaders blocked }} finally {finally { rwl.ReleaseWriterLock();rwl.ReleaseWriterLock(); }} }}}}

фдгдфгсдффдгдфгсдф

The Dining Philosophers The Dining Philosophers ProblemProblemНяколко философа стоятНяколко философа стоят

около кръгла маса и сеоколо кръгла маса и сехранят или мислятхранят или мислят

Когато се хранятКогато се хранят,, се нуждаят се нуждаяти от двете клечки от двете ими от двете клечки от двете имстранистрани

Условия:Условия:Не трябва никой философ да умре от гладНе трябва никой философ да умре от гладНе трябва да се позволява Не трябва да се позволява deadlock – deadlock – когато всеки когато всеки

философ има по една клечка и чака за другатафилософ има по една клечка и чака за другата

Класически синхр. проблемиКласически синхр. проблеми

фдгдфгсдффдгдфгсдф

CustomReaderWriterCustomReaderWriterclass CustomReaderWriterclass CustomReaderWriter{{ private int mReaders = 0;private int mReaders = 0; private bool mIsWriting = false;private bool mIsWriting = false; public void Read()public void Read() {{ lock( this )lock( this ) {{ whilewhile (mIsWriting) Monitor.Wait( this );(mIsWriting) Monitor.Wait( this ); mReaders++;mReaders++; }}

//...READING TAKES PLACE HERE...//...READING TAKES PLACE HERE...

lock( this ) lock( this ) {{ mReaders--;mReaders--; if( mReaders == 0 ) Monitor.Pulse(this);if( mReaders == 0 ) Monitor.Pulse(this); }} }} (примерът продължава)(примерът продължава)

фдгдфгсдффдгдфгсдф

CustomReaderWriterCustomReaderWriterclass CustomReaderWriterclass CustomReaderWriter{{ private int mReaders = 0;private int mReaders = 0; private bool mIsWriting = false;private bool mIsWriting = false; public void Read()public void Read() {{ lock( this )lock( this ) {{ whilewhile (mIsWriting) Monitor.Wait( this );(mIsWriting) Monitor.Wait( this ); mReaders++;mReaders++; }}

//...READING TAKES PLACE HERE...//...READING TAKES PLACE HERE...

lock( this ) lock( this ) {{ mReaders--;mReaders--; if( mReaders == 0 ) Monitor.Pulse(this);if( mReaders == 0 ) Monitor.Pulse(this); }} }} (примерът продължава)(примерът продължава)

фдгдфгсдффдгдфгсдф

CustomReaderWriterCustomReaderWriterclass CustomReaderWriterclass CustomReaderWriter{{ private int mReaders = 0;private int mReaders = 0; private bool mIsWriting = false;private bool mIsWriting = false; public void Read()public void Read() {{ lock( this )lock( this ) {{ whilewhile (mIsWriting) Monitor.Wait( this );(mIsWriting) Monitor.Wait( this ); mReaders++;mReaders++; }}

//...READING TAKES PLACE HERE...//...READING TAKES PLACE HERE...

lock( this ) lock( this ) {{ mReaders--;mReaders--; if( mReaders == 0 ) Monitor.Pulse(this);if( mReaders == 0 ) Monitor.Pulse(this); }} }} (примерът продължава)(примерът продължава)

фдгдфгсдффдгдфгсдф

CustomReaderWriterCustomReaderWriterclass CustomReaderWriterclass CustomReaderWriter{{ private int mReaders = 0;private int mReaders = 0; private bool mIsWriting = false;private bool mIsWriting = false; public void Read()public void Read() {{ lock( this )lock( this ) {{ whilewhile (mIsWriting) Monitor.Wait( this );(mIsWriting) Monitor.Wait( this ); mReaders++;mReaders++; }}

//...READING TAKES PLACE HERE...//...READING TAKES PLACE HERE...

lock( this ) lock( this ) {{ mReaders--;mReaders--; if( mReaders == 0 ) Monitor.Pulse(this);if( mReaders == 0 ) Monitor.Pulse(this); }} }} (примерът продължава)(примерът продължава)

фдгдфгсдффдгдфгсдф

CustomReaderWriterCustomReaderWriter public void Write()public void Write() {{ lock( this ) lock( this ) {{ while( mReaders != 0 )while( mReaders != 0 ) Monitor.Wait( this );Monitor.Wait( this ); mIsWriting = true;mIsWriting = true; }}

//...WRITING TAKES PLACE HERE...//...WRITING TAKES PLACE HERE...

lock( this ) lock( this ) {{ mIsWriting = false;mIsWriting = false; Monitor.PulseAll( this );Monitor.PulseAll( this ); }} }}}}

фдгдфгсдффдгдфгсдф

CustomReaderWriterCustomReaderWriter public void Write()public void Write() {{ lock( this ) lock( this ) {{ while( mReaders != 0 )while( mReaders != 0 ) Monitor.Wait( this );Monitor.Wait( this ); mIsWriting = true;mIsWriting = true; }}

//...WRITING TAKES PLACE HERE...//...WRITING TAKES PLACE HERE...

lock( this ) lock( this ) {{ mIsWriting = false;mIsWriting = false; Monitor.PulseAll( this );Monitor.PulseAll( this ); }} }}}}

фдгдфгсдффдгдфгсдф

CustomReaderWriterCustomReaderWriter public void Write()public void Write() {{ lock( this ) lock( this ) {{ while( mReaders != 0 )while( mReaders != 0 ) Monitor.Wait( this );Monitor.Wait( this ); mIsWriting = true;mIsWriting = true; }}

//...WRITING TAKES PLACE HERE...//...WRITING TAKES PLACE HERE...

lock( this ) lock( this ) {{ mIsWriting = false;mIsWriting = false; Monitor.PulseAll( this );Monitor.PulseAll( this ); }} }}}}

фдгдфгсдффдгдфгсдф

CustomReaderWriterCustomReaderWriter public void Write()public void Write() {{ lock( this ) lock( this ) {{ while( mReaders != 0 )while( mReaders != 0 ) Monitor.Wait( this );Monitor.Wait( this ); mIsWriting = true;mIsWriting = true; }}

//...WRITING TAKES PLACE HERE...//...WRITING TAKES PLACE HERE...

lock( this ) lock( this ) {{ mIsWriting = false;mIsWriting = false; Monitor.PulseAll( this );Monitor.PulseAll( this ); }} }}}}

фдгдфгсдффдгдфгсдф

Демонстрация #1Демонстрация #177

CustomReaderWriterCustomReaderWriter

фдгдфгсдффдгдфгсдф

Synchronized WrappersSynchronized Wrappers По подразбиране стандартните колекцииПо подразбиране стандартните колекции

((ArrayListArrayList, , QueueQueue, , StackStack) не са thread safe) не са thread safe HashtableHashtable е thread safe (1 писач, N четеца) е thread safe (1 писач, N четеца) Synchronized Wrapper е синхронизирана обвивка Synchronized Wrapper е синхронизирана обвивка

около колекциятаоколо колекцията Връща синхронизирана версия на колекциятаВръща синхронизирана версия на колекцията

При При HashtableHashtable – threadsafe (N писача, N четеца) – threadsafe (N писача, N четеца)

Свойството Свойството ICollection.SyncRootICollection.SyncRoot

Stack safeStack = Stack.Synchronized(stack);Stack safeStack = Stack.Synchronized(stack);

locklock (bitArray.SyncRoot)(bitArray.SyncRoot){ { //// Perform thread unsafe operations here Perform thread unsafe operations here } }

фдгдфгсдффдгдфгсдф

Нишки – препоръчвани практикиНишки – препоръчвани практики Избягвайте нуждата от синхронизацияИзбягвайте нуждата от синхронизация,, когато е когато е

възможновъзможно Използвайте Използвайте Interlocked Interlocked вместо синхронизациявместо синхронизация,,

където е възможнокъдето е възможно Пазете се от Пазете се от deadlocksdeadlocks Избягвайте Избягвайте lock(..){}lock(..){}, , ако е възможноако е възможно Правете критичните секции възможно най-кратки (за да Правете критичните секции възможно най-кратки (за да

намалите изчакването)намалите изчакването) Член-променливите не е нужно да са Член-променливите не е нужно да са thread safethread safe, ако не , ако не

се достъпват от други нишкисе достъпват от други нишки Статичните членове е нужно да са Статичните членове е нужно да са thread safethread safe Използвайте статични данни само за четене (Използвайте статични данни само за четене (read-only)read-only)

фдгдфгсдффдгдфгсдф

Асинхронни извиквания – Асинхронни извиквания – съдържаниесъдържание

МногозадачностМногозадачност НишкиНишки СинхронизацияСинхронизация Асинхронни извикванияАсинхронни извиквания

Асинхронни извиквания на методиАсинхронни извиквания на методиКъде се поддържа?Къде се поддържа?Асинхронно извикване чрез делегатАсинхронно извикване чрез делегатDesign Pattern за асинхр. извикванияDesign Pattern за асинхр. извикванияИнтерфейсът Интерфейсът IAsyncResultIAsyncResultРезултат от асинхронен методРезултат от асинхронен метод

фдгдфгсдффдгдфгсдф

Асинхронни извиквания на методиАсинхронни извиквания на методи По подразбиране един метод се дефинира По подразбиране един метод се дефинира

като синхронен (като синхронен (synchronous)synchronous) Синхронно извикванеСинхронно извикване на метод на метод

(synchronous method call)(synchronous method call) Изчаква се неговото приключване и след това се Изчаква се неговото приключване и след това се

преминава към следващия операторпреминава към следващия оператор Асинхронно извикване на метод Асинхронно извикване на метод

((asynchronous method call)asynchronous method call) Без да се чака приключването на метода, се минава Без да се чака приключването на метода, се минава

на следващия операторна следващия оператор Механизмът на асинхронното извикване Механизмът на асинхронното извикване

използва нишки (използва нишки (ThreadPoolThreadPool))

фдгдфгсдффдгдфгсдф

Къде се поддържа?Къде се поддържа?

Вход/изход: File IO, Stream IO, Socket IOВход/изход: File IO, Stream IO, Socket IO Мрежови класове: HTTP, TCPМрежови класове: HTTP, TCP Remoting канали (HTTP, TCP) и прокситаRemoting канали (HTTP, TCP) и проксита ASP.NET XML Web-услугиASP.NET XML Web-услуги ASP.NET Web-приложенияASP.NET Web-приложения При работа с MSMQ (При работа с MSMQ (Microsoft Message Queue)Microsoft Message Queue) Асинхронни делегатиАсинхронни делегати Потребителски класове, дефиниращи Потребителски класове, дефиниращи

асинхронен интерфейс за извикванеасинхронен интерфейс за извикване

фдгдфгсдффдгдфгсдф

Асинхронно извикване чрез делегатАсинхронно извикване чрез делегат

Делегатите предоставят функционалност Делегатите предоставят функционалност за асинхронно извикване на синхронен за асинхронно извикване на синхронен методметодАвтоматично се генерират Автоматично се генерират BeginInvoke()BeginInvoke() и и EndInvoke()EndInvoke() с правилния брой параметри с правилния брой параметри

Генерирането става при създаването на Генерирането става при създаването на делегат със съответната сигнатураделегат със съответната сигнатура

Добавя се функционалност без да се Добавя се функционалност без да се изисква нито ред допълнителен кодизисква нито ред допълнителен код

фдгдфгсдффдгдфгсдф

Асинхронно извикване чрез делегатАсинхронно извикване чрез делегат

using System;using System;using System.Threading;using System.Threading;

class AsyncCallclass AsyncCall{{ public delegate int MyDelegate(int a, int b);public delegate int MyDelegate(int a, int b);

public int Sum(int a, int b)public int Sum(int a, int b) {{ Thread.Sleep(3000);Thread.Sleep(3000); return a+b;return a+b; }}

static void Main(string[] args)static void Main(string[] args) {{ MyDelegate asyncCall = new MyDelegate(newMyDelegate asyncCall = new MyDelegate(new AsyncCall().Sum);AsyncCall().Sum); Console.WriteLine("Console.WriteLine("SStarting method async.");tarting method async.");

фдгдфгсдффдгдфгсдф

Асинхронно извикване чрез делегатАсинхронно извикване чрез делегат

IAsyncResult status =IAsyncResult status = asyncCall.asyncCall.BeginInvokeBeginInvoke(5, 6, null, null);(5, 6, null, null); Console.WriteLine("Async method is working");Console.WriteLine("Async method is working");

Console.WriteLine("Calling EndInvoke()");Console.WriteLine("Calling EndInvoke()"); int result = asyncCall.int result = asyncCall.EndInvokeEndInvoke(status);(status); Console.WriteLine("EndInvoke() returned");Console.WriteLine("EndInvoke() returned"); Console.WriteLine("Result={0}", result);Console.WriteLine("Result={0}", result); }}}}

//// РезултатРезултат::Starting method asynchronouslyStarting method asynchronouslyAsynchronous method is working nowAsynchronous method is working nowCalling EndInvoke() Calling EndInvoke() //// тук има пауза, заради Sleepтук има пауза, заради Sleep()()EndInvoke() returnedEndInvoke() returnedResult=11Result=11

фдгдфгсдффдгдфгсдф

Демонстрация #18Демонстрация #18

Асинхронно извикване чрез делегатАсинхронно извикване чрез делегат

фдгдфгсдффдгдфгсдф

Design Pattern Design Pattern зазаасинхронно програмиранеасинхронно програмиране

Случаи, в които се налага изричното Случаи, в които се налага изричното имплементиране на асинхронно имплементиране на асинхронно извикване на методизвикване на методАко изричното имплементиране е по-бързо Ако изричното имплементиране е по-бързо

от извикване с делегатот извикване с делегатАко методът трябва да се извиква само Ако методът трябва да се извиква само

асинхронноасинхронно В такива случаи строго се препоръчва В такива случаи строго се препоръчва

следването на следването на design pattern-a design pattern-a

фдгдфгсдффдгдфгсдф

Асинхронно програмиранеАсинхронно програмиране Нека имаме синхронен методНека имаме синхронен метод

Искаме да предоставим асинхронна версияИскаме да предоставим асинхронна версия В .NET Framework асинхронното извикване се В .NET Framework асинхронното извикване се

характеризира с използването на методите характеризира с използването на методите BeginXXXXXBeginXXXXX и и EndXXXXXEndXXXXX, където , където XXXXXXXXXX е е синхронната версия на методасинхронната версия на метода

Асинхронната версия на метода Асинхронната версия на метода SumSum е: е:

int Sum(int a, int b);int Sum(int a, int b);

IAsyncResult BeginSum(int a, int b,IAsyncResult BeginSum(int a, int b, AsyncCallback requestCallback,AsyncCallback requestCallback, object stateObject);object stateObject);

int EndSum(IASyncResult ar);int EndSum(IASyncResult ar);

фдгдфгсдффдгдфгсдф

Асинхронно програмиранеАсинхронно програмиране Нека имаме синхронен методНека имаме синхронен метод

Искаме да предоставим асинхронна версияИскаме да предоставим асинхронна версия В .NET Framework асинхронното извикване се В .NET Framework асинхронното извикване се

характеризира с използването на методите характеризира с използването на методите BeginXXXXXBeginXXXXX и и EndXXXXXEndXXXXX, където , където XXXXXXXXXX е е синхронната версия на методасинхронната версия на метода

Асинхронната версия на метода Асинхронната версия на метода SumSum е: е:

int int SumSum(int a, int b);(int a, int b);

IAsyncResult IAsyncResult BeginSumBeginSum(int a, int b,(int a, int b, AsyncCallback requestCallback,AsyncCallback requestCallback, object stateObject);object stateObject);

int int EndSumEndSum(IASyncResult ar);(IASyncResult ar);

фдгдфгсдффдгдфгсдф

Асинхронно програмиранеАсинхронно програмиране Нека имаме синхронен методНека имаме синхронен метод

Искаме да предоставим асинхронна версияИскаме да предоставим асинхронна версия В .NET Framework асинхронното извикване се В .NET Framework асинхронното извикване се

характеризира с използването на методите характеризира с използването на методите BeginXXXXXBeginXXXXX и и EndXXXXXEndXXXXX, където , където XXXXXXXXXX е е синхронната версия на методасинхронната версия на метода

Асинхронната версия на метода Асинхронната версия на метода SumSum е: е:

int Sum(int Sum(int a, int bint a, int b););

IAsyncResult BeginSum(IAsyncResult BeginSum(int a, int bint a, int b,, AsyncCallback requestCallback,AsyncCallback requestCallback, object stateObject);object stateObject);

int EndSum(IASyncResult ar);int EndSum(IASyncResult ar);

фдгдфгсдффдгдфгсдф

Асинхронно програмиранеАсинхронно програмиране Нека имаме синхронен методНека имаме синхронен метод

Искаме да предоставим асинхронна версияИскаме да предоставим асинхронна версия В .NET Framework асинхронното извикване се В .NET Framework асинхронното извикване се

характеризира с използването на методите характеризира с използването на методите BeginXXXXXBeginXXXXX и и EndXXXXXEndXXXXX, където , където XXXXXXXXXX е е синхронната версия на методасинхронната версия на метода

Асинхронната версия на метода Асинхронната версия на метода SumSum е: е:

intint Sum(int a, int b); Sum(int a, int b);

IAsyncResult BeginSum(int a, int b,IAsyncResult BeginSum(int a, int b, AsyncCallback requestCallback,AsyncCallback requestCallback, object stateObject);object stateObject);

intint EndSum(IASyncResult ar); EndSum(IASyncResult ar);

фдгдфгсдффдгдфгсдф

Асинхронно програмиранеАсинхронно програмиране Нека имаме синхронен методНека имаме синхронен метод

Искаме да предоставим асинхронна версияИскаме да предоставим асинхронна версия В .NET Framework асинхронното извикване се В .NET Framework асинхронното извикване се

характеризира с използването на методите характеризира с използването на методите BeginXXXXXBeginXXXXX и и EndXXXXXEndXXXXX, където , където XXXXXXXXXX е е синхронната версия на методасинхронната версия на метода

Асинхронната версия на метода Асинхронната версия на метода SumSum е: е:

int Sum(int a, int b);int Sum(int a, int b);

IAsyncResultIAsyncResult BeginSum(int a, int b, BeginSum(int a, int b, AsyncCallback requestCallbackAsyncCallback requestCallback,, object stateObject);object stateObject);

int EndSum(IASyncResult ar);int EndSum(IASyncResult ar);

delegate void AsyncCallback(IASyncResult ar);delegate void AsyncCallback(IASyncResult ar);

фдгдфгсдффдгдфгсдф

Асинхронно програмиранеАсинхронно програмиране Нека имаме синхронен методНека имаме синхронен метод

Искаме да предоставим асинхронна версияИскаме да предоставим асинхронна версия В .NET Framework асинхронното извикване се В .NET Framework асинхронното извикване се

характеризира с използването на методите характеризира с използването на методите BeginXXXXXBeginXXXXX и и EndXXXXXEndXXXXX, където , където XXXXXXXXXX е е синхронната версия на методасинхронната версия на метода

Асинхронната версия на метода Асинхронната версия на метода SumSum е: е:

int Sum(int a, int b);int Sum(int a, int b);

IAsyncResult BeginSum(int a, int b,IAsyncResult BeginSum(int a, int b, AsyncCallback requestCallback,AsyncCallback requestCallback, object stateObjectobject stateObject););

int EndSum(IASyncResult ar);int EndSum(IASyncResult ar);

фдгдфгсдффдгдфгсдф

Асинхронно програмиранеАсинхронно програмиране Нека имаме синхронен методНека имаме синхронен метод

Искаме да предоставим асинхронна версияИскаме да предоставим асинхронна версия В .NET Framework асинхронното извикване се В .NET Framework асинхронното извикване се

характеризира с използването на методите характеризира с използването на методите BeginXXXXXBeginXXXXX и и EndXXXXXEndXXXXX, където , където XXXXXXXXXX е е синхронната версия на методасинхронната версия на метода

Асинхронната версия на метода Асинхронната версия на метода SumSum е: е:

int Sum(int a, int b);int Sum(int a, int b);

IAsyncResult BeginSum(int a, int b,IAsyncResult BeginSum(int a, int b, AsyncCallback requestCallback,AsyncCallback requestCallback, object stateObject);object stateObject);

int EndSum(IASyncResult ar);int EndSum(IASyncResult ar);

фдгдфгсдффдгдфгсдф

IAsyncResultIAsyncResult

Свойството Свойството AsyncStateAsyncState, връща същия обект подаден , връща същия обект подаден като като stateObjectstateObject на на BeginBeginInvoke()Invoke()

Предоставя се, за да се използва от потребителя, като Предоставя се, за да се използва от потребителя, като начин за следене на статусаначин за следене на статуса

Не се използва или променя по какъвто и да било Не се използва или променя по какъвто и да било начин от извиквания методначин от извиквания метод

public interface IAsyncResultpublic interface IAsyncResult{{ object AsyncState {get;}object AsyncState {get;} WaitHandle AsyncWaitHandle {get;} WaitHandle AsyncWaitHandle {get;} bool CompletedSynchronously {get;}bool CompletedSynchronously {get;} bool IsCompleted {get;}bool IsCompleted {get;}}}

фдгдфгсдффдгдфгсдф

IAsyncResultIAsyncResult

Свойството Свойството AsyncWaitHandleAsyncWaitHandle се използва като се използва като параметър на методите параметър на методите WaitAll()WaitAll(), , WaitOne()WaitOne() или или WaitAny()WaitAny() на класа на класа WaitHandleWaitHandle за изчакване за изчакване приключването на асинхронния методприключването на асинхронния метод

Гореописаният механизъм е един от начините за Гореописаният механизъм е един от начините за приключване на асинхронен методприключване на асинхронен метод

public interface IAsyncResultpublic interface IAsyncResult{{ object AsyncState {get;}object AsyncState {get;} WaitHandle AsyncWaitHandle {get;} WaitHandle AsyncWaitHandle {get;} bool CompletedSynchronously {get;}bool CompletedSynchronously {get;} bool IsCompleted {get;}bool IsCompleted {get;}}}

фдгдфгсдффдгдфгсдф

IAsyncResultIAsyncResult

CompletedSynchronouslyCompletedSynchronously връща връща truetrue ако ако асинхронният метод е приключил работа асинхронният метод е приключил работа преди края на извикването на преди края на извикването на BeginBeginInvokeInvoke

метода (т.е. ако работи прекалено бързометода (т.е. ако работи прекалено бързо))

public interface IAsyncResultpublic interface IAsyncResult{{ object AsyncState {get;}object AsyncState {get;} WaitHandle AsyncWaitHandle {get;} WaitHandle AsyncWaitHandle {get;} bool CompletedSynchronously {get;}bool CompletedSynchronously {get;} bool IsCompleted {get;}bool IsCompleted {get;}}}

фдгдфгсдффдгдфгсдф

IAsyncResultIAsyncResult

IsCompletedIsCompleted връща връща truetrue ако асинхронният ако асинхронният метод е приключил работаметод е приключил работа

Може да се използва чрез механизма "polling" – Може да се използва чрез механизма "polling" – през определено време да се проверява през определено време да се проверява истинността на истинността на IsCompletedIsCompleted докато върне докато върне truetrue

public interface IAsyncResultpublic interface IAsyncResult{{ object AsyncState {get;}object AsyncState {get;} WaitHandle AsyncWaitHandle {get;} WaitHandle AsyncWaitHandle {get;} bool CompletedSynchronously {get;}bool CompletedSynchronously {get;} bool IsCompleted {get;}bool IsCompleted {get;}}}

фдгдфгсдффдгдфгсдф

Изчакване на асинхронен методИзчакване на асинхронен метод Има 4 начина да се провери дали е Има 4 начина да се провери дали е

приключил един асинхронен методприключил един асинхронен метод1.1. Механизмът "polling" – проверява се Механизмът "polling" – проверява се

IAsyncResult.IsCompletedIAsyncResult.IsCompleted през през определено времеопределено време

2.2. Чрез Чрез WaitHandle.WaitOne() / WaitHandle.WaitOne() / WaitAll() / WaitAny() WaitAll() / WaitAny() върху върху IAsyncResult.AsyncWaitHandleIAsyncResult.AsyncWaitHandle

Може да се задава таймаут, за да не се Може да се задава таймаут, за да не се чака безкрайно дългочака безкрайно дълго

3.3. Извикване на Извикване на EndEndInvokeInvoke()(), който , който блокира докато асинхронният метод не блокира докато асинхронният метод не свърши работата сисвърши работата си

фдгдфгсдффдгдфгсдф

Изчакване на асинхронен методИзчакване на асинхронен метод Има 4 начина да се провери дали е Има 4 начина да се провери дали е

приключил един асинхронен методприключил един асинхронен метод

4.4. Да се подаде callback метод на Да се подаде callback метод на BeginBeginInvokeInvoke()() чрез делегата чрез делегата AsyncCallbackAsyncCallback

Подаденият метод се извиква, когато Подаденият метод се извиква, когато асинхронният метод приключи работаасинхронният метод приключи работа

От него може да се извика От него може да се извика EndEndInvokeInvoke()() за за да се извлече резултатада се извлече резултата

delegate void AsyncCallback(IASyncResultdelegate void AsyncCallback(IASyncResult ar)ar)

фдгдфгсдффдгдфгсдф

Демонстрация #19Демонстрация #19 4 начина да изчакаме приключването на 4 начина да изчакаме приключването на

асинхронно извикванеасинхронно извикване