View
2.256
Download
4
Category
Preview:
Citation preview
TPL – konkurenční, paralelní a asynchronní
kód pro náročné
René Steinhttp://renestein.net
TPL základy – co byste měli znát
• Třída Task. „Thread je mrtev, ať žije Task“?
• Spuštění tásku a základní operace pro skládání tásků (WaitAny, WaitAll).
• Kooperativní stornování tásku.
• Co je synchronizační kontext a proč máme metodu ConfigureAwait.
• Klíčová slov async a await v C#.
TPL základy – co byste měli znát II
• Asynchronní != paralelní. (a asynchronní nebo paralelní != zázrak)
• Proč bychom neměli používat async void metody.
• Jaký je životní cyklus objektu tásku?
• (Toto by neměl být váš životní cyklus)
„Přišel jsem, viděl jsem, bohatě stačilo a (nejpozději po svačině) rád odcházím“
Životní cyklus tásku
Zdroj: http://blog.stephencleary.com/2014/06/a-tour-of-task-part-3-status.html
Něco jednoduchého – problémy s TaskCompletionSource
„Co jednou Task spojil, toTaskCompletionSource
musí rozdělit“Věčnost?
TaskCompletionSource
• TaskCompletionSource = Promise.
• Task = Future.
• I při kódování by se sliby měly plnit. I když to občas znamená, že ten druhý si bude přát, abyste mu nikdy nic neslíbili, protože může od vás čekat je krev, pot, slzy, deadlock, a když jste v dobrém rozmaru, tak výjimku BTW:Jsou sliby oboustranné?
Rstein.Async – DebugTaskCompletionSource
• DebugTaskCompletionSourceServices.DetectBrokenTaskCompletionSources();
(Detekce nesplněných slibů bez záruky - jde jen o preview verzi)
Idioti jsou jako láska - slibují víc, než mohou splnit. (G. Laub) Na TaskCompletionSource bych v této souvislosti nezapomínal!
(Dodatek: René Stein)
Každý slib je na nejlepší cestě k tomu být falešný. (J.P. Sartre)
Scheduler a ThreadPool
TPL scheduler.Net ThreadPool
TPL scheduler se má k .Net
ThreadPoolu jako ?
TPL scheduler se má k .Net
ThreadPoolu jako ?
Co s hříšnými touhami po jiném Scheduleru?
•Potřebujeme jiné schedulery než ty, které jsou v .Net Frameworku?– „ThreadPoolScheduler“ - Default – „SynchronizationContextScheduler“
FromCurrentSynchronizationContext()– ConcurrentExclusiveSchedulerPair (náhrada
za „lock“, ReaderWriterLock)
• !!! Většinou ne !!! - ale když už ano
„Extra“ schedulery v PEE
•Další slušnou sbírku schedulerů naleznete v Parallel Extensions Extras
http://code.msdn.microsoft.com/ParExtSamples
Vlastní scheduler
Nejjednodušší je podle mě:
CurrentThreadScheduler(A v téhle jednoduchosti fakt nehledejte
žádnou krásu)
Vlastní scheduler – problémy a řešení
(Otravný) FallbackScheduler, který může použít CurrentThreadScheduler jako záložní scheduler
Rstein.Async – dvojice IProxyScheduler a ITaskScheduler
Integrace s TPL – „obyčejný“
TaskScheduler
Rstein.Async – ProxyScheduler a TaskSchedulerBase
FallbackScheduler s pořadovým číslem 2 je sice stále nudný, ale už jej alespoň dokážeme napsat a používat bez vyvolání výjimky.
FALLBACKSCHEDULER II
Rstein.Async a IoServiceScheduler
• Scheduler, který nevyřídí žádný tásk do té doby, dokud mu nepropůjčíte vlákno zavoláním jedné z jeho metod Poll, PollOne, Run, RunOne
• Boost.Asio .Net
Rstein.Async - IoServiceSynchronizationContext
Rstein.Async a IoServiceThreadPoolScheduler
• „Autonomní“ scheduler.
• (Velmi) jednoduchý threadpool.
• Používá IoServiceScheduler.
Nelehký životní cyklus SimpleUploaderu
• Jak by řekla nejen programátorka Maruška – funkčnost a čitelnost kódu nad zlato i rychlost.
• V praxi se nejčastěji setkáte s kódem, který je:– Občas nefunkční, ale nikdo neví „proč“.– Nečitelný, ale všichni vám zdůvodní „proč“.– Po čase pomalý a plný (dead)locků, které
jsou zpestřením nudného vývojářského života. Proč?
Aktor model
• Zjednodušeně – aktor je objekt (prozatím nekamenovat!), u kterého platí, že v jednom okamžiku zpracovává maximálně jednu zprávu („provádí jednu metodu“). A to bez ohledu na počet požadavků z různých vláken.
• Všechny požadavky na aktora jsou aktorem zpracovány sekvenčně!
Aktor jako objekt z lepší společnosti
• Objekty, u kterých se při volání metody může změnit jejich interní stav (a přitom se zbavíme „locků“)
• Aktor je (prý) lepší objekt než “klasické“ objekty (nejen) z C-like jazyků.
Charakteristika konvenčního aktor modelu
• Aktor při zpracování zprávy („po obdržení požadavku“) může:– Poslat zprávy (požadavky) dalším aktorům.– Změnit svůj stav. A připravit se tak na příjem
další zprávy (požadavku).– Vytvořit další aktory pro zpracování nových
zpráv (požadavků).
Aktoři a thready
• Jak zabít aktory i s aplikaci? Frontu požadavků každého aktora obsluhuje právě jeden thread. Tento thread je v exkluzivním vlastnictví aktora.
• Co je „threadless“ actor model?
Rstein.Async - StrandSchedulerDecorator
• STRAND = v jednom okamžiku běží maximálně jeden tásk
• Implicitní strand = m_originalScheduler.MaximumConcurrencyLevel = 1
StrandSchedulerDecorator
ITaskScheduler(nejčastěji
IoServiceThreadPoolScheduler)
Rstein.Async - podpora pro aktory
• Použita dynamická proxy
• Castle.DynamicProxy
•
var uploaderActorProxy = proxyEngine.CreateProxy<IService>(simpleUploaderActor);
ProxyGenerationHook „Jaké metody budeme
odchytávat v interceptorech“
ActorMethodInterceptor „metody budou zpracovány sekvenčně – každý aktor má svůj StrandScheduler“
PreventArgumentBaseTypeLeakInterceptor„Aktor nevydá svou pravou podstatu z žádné metody, ale vždy si navlékne proxy masku“
Tradiční ukázky aktorů I
Ping Pong (Tomáš Aquinský proti Sigeru
Brabantskému)
Tradiční ukázky aktorů II
(Problematický) Ping Pong s čekáním na odpověď
• Podle mě je takzvaný „ASK“ vzor pro většinu scénářů antivzor. „Don‘t ASK“
• Actor by měl komunikovat s ostatními aktory stylem „Fire & Forget”.– Budeme čekat na odpověď a blokovat
zpracování dalších zpráv?– Zpracujeme jinou zprávu?
(co vnitřní stav aktora?)
Schéma komunikace mezi aktory - ukázka III
ILibraryActor IBookLinesParserActor
IBookLineConsumerActor n(CountWordsInLineActor)
ICountWordAggregateActor
IBookLineConsumerActor 1(CountWordsInLineActor)
IResultProcessorActor(PrintTopWordsProces
sorActor)
Co naši aktoři prozatím nepodporují
• O „pravém“ actor modelu (Erlang, Elixir…) se dá mluvit teprve tehdy:– Jsme-li schopni aktory od sebe dokonale izolovat.– Jsme-li schopni aktory aktivovat v jiném procesu/na
jiném počítači (distribuovaní aktoři). Ošetření chyb např. elegantním a vývojáři milovaným stylem „Let it crash“.
• Přesto – i „naši“ zjednodušení aktoři jsou pro mnoho aplikací požehnáním
Alternativní knihovny pro psaní aktorů
• TPL Dataflow – např. pomocí ActionBlocku s konkurencí rovnou jedné.
• ActorFX - http://actorfx.codeplex.com/wikipage?title=ActorFx%20Basics
• F#
Zdroj: http://blogs.msdn.com/b/dsyme/archive/2010/02/15/async-and-parallel-design-patterns-in-f-part-3-agents.aspx
AKKA.NET
Zdroj: https://github.com/akkadotnet/akka.net/issues/144
Tradiční problémy s aktory
• Jestliže aktoři mohou modifikovat stav „zpráv“ (argumentů metod), máte „race condition“. Zprávy-argumenty musí být imutabilní.
• Ani použití aktorů neznamená jistotu, že se v aplikaci neobjeví deadlock.
• Jeden aktor se může snadno stát brzdou pro ostatních aktory. Výkonnostní problémy.
Alternativní konkurenční modely
• TPL Dataflow
• Reactive Extensions – RX framework
• Software transactional memory
• Communicating Sequential Processes (CSP)
• a mnoho dalších
Zdroje – malý výběr
• Knihovna Rstein.Async.
https://bitbucket.org/renestein/rstein.async/
• Seriál na blogu o knihovně (prozatím 5 dílů) http://jdem.cz/ba8kp3
Answer? answer = await Task.Run(()=>
);
Dotazy
René Stein
• Vývoj aplikací, veřejné a inhouse kurzy
• http://www.renestein.net/nabidka.aspx
http://blog.renestein.nethttp://twitter.com/renestein
Recommended