1 / 87

SDP - Repetition

SDP - Repetition. Sockets Trådning Delegater Remoting Sprogteori. Sockets. Logiske endepunkter mellem server og klient På applikationsniveauet betragtes Sockets som pålidelige Sockets optræder parvis Til en Socket er der via en NetworkStream knyttet både en StreamReader StreamWriter

vaughan
Download Presentation

SDP - Repetition

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. SDP - Repetition • Sockets • Trådning • Delegater • Remoting • Sprogteori

  2. Sockets • Logiske endepunkter mellem server og klient • På applikationsniveauet betragtes Sockets som pålidelige • Sockets optræder parvis • Til en Socket er der via en NetworkStream knyttet både en • StreamReader • StreamWriter • Klientens StreamReader er forbundet til serverens StreamWriter og omvendt

  3. Sockets - Arkitektur

  4. Sockets - Serversiden • Skab en TcpListener på port 20001 (fx) TcpListener server = new TcpListener(IPAddress.Any, 20001); server.Start(); • Vent på forespørgsel fra klient while(true) { Socket klient = server.AcceptSocket(); } • Skab StreamReader og StreamWriter ud fra Socket NetworkStream stream = new NetworkStream(klient); StreamReader reader = new StreamReader(stream); StreamWriter writer = new StreamWriter(stream); writer.AutoFlush = true; • Send og modtag via StreamReader og StreamWriter reader.ReadLine(); writer.WriteLine(); • Luk strømme og Sockets

  5. Sockets - Klientsiden • Skab en Socket til serveren TcpClient server = new TcpClient(”localhost”, 20001); • Skab StreamReader og StreamWriter ud fra Socket NetworkStream stream = server.GetStream(); StreamReader reader = new StreamReader(stream); StreamWriter writer = new StreamWriter(stream); writer.AutoFlush = true; • Send og modtag via StreamReader og StreamWriter reader.ReadLine(); writer.WriteLine(); • Luk strømme og Socket

  6. Flere samtidige klienter • Server class Server { publicstaticvoid) { TcpListener server = new TcpListener(IPAddress.Any, 20001) server.Start(); while (true) { Socket klient = server.AcceptSocket(); new Thread(new ThreadStart(new ClientHandler(klient).Run)).Start(); } } }

  7. Flere samtidige klienter • ClientHandler class ClientHandler { private Socket incoming; public ClientHandler(Socket incoming) { this.incoming = incoming; } publicvoid Run() { // Instantiér ind- og ud-strøm while (true) { // Kommunikér } } }

  8. Hvorfor trådning? • Performance • Responsivness

  9. Succeskriterier • Forbedring af performance • Opgaverne skal være uafhængige • Jo flere afhængige opgaver, jo mindre forbedring • Forbedring af responsivness • Responsivness er et spørgsmål om oplevelse • Jo længere tid en opgave tager, jo mindre virksom opleves applikationen, hvis brugeren ikke har noget at lave eller se på

  10. Fordele • Overvågningssystemer med flere uafhængige opgaver • Muliggør brugerinteraktion via BGF • Muliggør serverhåndtering af flere samtidige klienter • Udnytter flerprocessor-systemer optimalt

  11. Ulemper • Trådene afvikles uafhængigt af hverandre • Afviklingsrækkefølgen synes vilkårlig • Samspillet mellem tråde er ofte meget kompleks • Problemer med safety og liveness

  12. Trådskifte • CPU’en skifter til en ny tråd … • Efter et givent tidsrum, eller • Når en tråd venter på færdiggørelsen af en opgave, fx en I/O-operation …

  13. Processer vs. Tråde • Der er mindst to former for samtidighed: • Multiprocessing • Multithreading

  14. Multiprocessing • Samtidighed på tværs af applikationer • Til heavy-weight opgaver(IIS, SQL, Server, …) • Hver proces eksekverer én enkelt tråd

  15. Multithreading • Samtidighed i applikationer • Forskellige tråde udfører forskellige opgaver • Perfekt til light-weight opgaver(Metodekald, UI-opdateringer, …)

  16. Multithreading • Samtidighed i .NET • Tråde håndteres af CLR • Tråde har deres egen stak (locals), men deler globals og heap

  17. Instantiering af tråde • Tråde kaldes ikke, de startes … • Man kan derfor ikke medsende parametre, modtage returværdi og fange exceptions på sædvanlig vis • Trådet kode skal håndtere fejl … • Uhåndterede fejl vil terminere applikationen • Gør designet simpelt … • Trådning er et minefelt – fælles ressourcer giver anledning til kritiske sektioner, race conditions, deadlock, …

  18. Instantiering af tråde publicstaticvoid Main() { Thread t; t = new Thread(new ThreadStart(Run)); t.Start() } publicstaticvoid Run() { // kode }

  19. Trådes livscyklus

  20. Trådsikre klasser • Problem • Hvis en tråd afbrydes, medens den arbejder på et objekt, er der risiko for, at objektet efterlades i eninkonsistent tilstand.Dette kan give problemer, når en anden tråd forsøger at få tilgang til objektet

  21. Trådsikre klasser • Løsning • Løsningen er at forhindre mere end én tråd ad gangen i at få tilgang til de kritiske områder i koden

  22. Single Threaded Execution • Vha. lock(obj) opnår en tråd eneret på et objekt – en lås • Låsen frigives, når tråden forlader det kritiske område eller ved kald af metoden Monitor.Wait(obj) på objektet. • Kritiske områder på samme objekt deler samme lås!

  23. Liveness problemer • Starvation (udhungring) • En tråd, som er i tilstanden ready, får aldrig lejlighed til at køre, fordi der findes andre tråde med højere prioritet • Dormancy (dvale) • En tråd, som er i tilstandenblocked on wait, vækkes aldrig med Monitor.Pulse() • Deadlock (hårdknude) • To eller flere tråde kæmper om flere fælles ressourcer, og hver tråd efterspørger på samme tid disse ressourcer • Premature Termination (for tidlig død) • En tråd termineres for tidligt og hindrer derved andre tråde i at blive vækket. (Evig dvale)

  24. Brug af lock() • Nødvendig, hvis man vil lave "trådsikre klasser" • Ej omkostningsfrit:Kræver CPU-kraft  langsommere programafvikling • "Hellere for mange synkroniserede blokke end for få!"MEN - pas på deadlocks

  25. lock vs. Monitor.Enter/Exit • lock(obj) er et alias for: try { Monitor.Enter(obj); // kode ... Monitor.Exit(obj); } catch { } finally { Monitor.Exit(obj); }

  26. Monitor • Monitor • indkapsler fælles ressourcer som private attributter og sikrer trådene enetilgang vha. lock() til de kritiske områder • Formål • Overvågning af trådes adgang til fælles ressourcer

  27. Monitor • Objekt, hvor de fælles ressourcer er samlet som attributter • Der er udelelig adgang til monitorens kritiske områder • Én monitor-lock pr. kritiskområde

  28. Early notification • Problem • Monitor.Pulse() sendes før betingelserne for Monitor.Wait er opfyldt • Konsekvens • Wait-tråden vækkes før tid • Løsning • Gentjek betingelserne for Monitor.Wait, når Wait-tråden vækkes • Konklusion • Anvend altid while (i stedet for if) i forbindelse med check af wait-betingelser

  29. Early notification • Bufferen er tom! • C1-tråden er i Wait-tilstand • P-tråden generer et nyt element og kalder monitorens synkroniserede put-metode • C1-tråden underrettes via Pulse, og tråden går i ready-tilstand • P-tråden forlader monitorens put-metode og slipper objekt-låsen på monitoren • Bufferen indeholder nu ét element! • Trådskifte! • C2-tråden trækker et element fra bufferen ved at kalde monitorens get-metode • C2-tråden forlader monitorens get-metode og slipper objekt-låsen på monitoren • Der er ingen elementer i bufferen! • Trådskifte! • C1 fortsætter nu fra Wait i monitorens get-metode i forsøget på at trække endnu et element fra bufferen … Dette er ikke muligt!

  30. Guarded Suspension publicvoid Put(int data) { lock(this) { while (queue.Full) Monitor.Wait(this); if (queue.Empty) Monitor.PulseAll(this); this.queue.Enqueue(data); } }

  31. Guarded Suspension publicvoid Get(int data) { lock(this) { while (queue.Empty) Monitor.Wait(this); if (queue.Full) Monitor.PulseAll(this); this.queue.Dequeue(data); } }

  32. Design af trådet applikation • Anvend Producer-Consumer mønstret • Anvend de 10 gode trådråd • Husk den gyldne regel

  33. 10 gode trådråd • Bestem tråde • Bestem trådmetoder • Bestem fælles ressourcer • Bestem monitorer - Én monitor for hver uafhængig fælles ressource • Bestem monitor-klasser • Bestem kritiske sektioner • Bestem Wait/Pulse – Et par for hver tilstand, som kræver, at en tråd venter på en anden • Fordel Wait og Pulse (Husk ”Guarded Suspension”-mønstret) • Lav pseudo-kode for monitor-klassernes metoder • Lav pseudo-kode for tråd-klassernes run-metoder

  34. Den gyldne UI-regel • UI-baserede .NET-applikationer • Den tråd, som har skabt UI’en ejer UI’en – Ingen anden tråd må tilgå UI’ens kontrolelementer …

  35. Delegater • Delegater er objekter, der refererer til en metode – tænk ”funktionspointer” delegate private void MinMethod(...) { . . . } • - med delegater kan man kalde en underliggende metode på en typesikker måde • - med delegater kan man arbejde med metodereferencer på en objektorienteret facon

  36. delegate Window Forms • Hvordan ved en knap, hvilken metode den skal kalde ved et click-event? • Det ved den heller ikke! Den kalder metoden bagved delegaten … Button Click: private void btnAdd_Click(object sender, EventArgs e) { int i, j, k; i = int.Parse(this.txtNumber1.Text); j = int.Parse(this.txtNumber2.Text); k = i + j; System.Windows.Forms.MessageBox.Show("Sum = " + k); }

  37. Delegat-baseret kode i VS . . . this.btnAdd = new Button(); this.btnAdd.Click += new System.EventHandler(this.btnAdd_Click);

  38. Remoting Server.exe (.NET) Client.exe (.NET) • Klienten ser serveren som en assembly (dll) • Referencen sættes på sædvanlig vis … • Serveren gør dll’en tilgængelig på flg. måder • Tjeneste på en server, der svarer på kald fra klienter. Effektivt! • Integreret i en web-tjeneste, der kaldes via URL. ”Firewall-venligt”!

  39. Komponent-dll • MBR-objekter arver fra MarshalByRefObject • MBV-objekter skal være Serializable namespace Komponent { public class Beregningsobjekt : System.MarshalByRefObject{ private static int Objekttæller = 0; private int ObjektID; // Konstruktør public Beregningsobjekt() { this.ObjektID = ++Objekttæller; } public DataObjekt HentDataObject() { return new DataObjekt(); } } namespace Komponent { [System.Serializable()] public class DataObjekt{ . . . } }

  40. Server Client stub proxy remoting remoting formatter channel formatter listener Remoting - arkitektur • Generel arkitektur • Proxy, stub, formattering og channel kan ændres. Fx er en binær formattering, der både understøttes af TCP og HTTP, mere effektiv end en tekstbaseret (XML)

  41. Remoting - Design • Designbeslutning: MBRO eller MBVO? • Med andre ord: ”Hvor skal objekterne leve?” • MBRO lever på serveren • MBVO lever på klienten • Gængs praksis: • Beregninger sker på serveren  MBRO • Fx søgning og køb på en ehandel • Tilstande bevares på klienten  MBVO • Fx indkøbskurv på en ehandel håndteres af klienten

  42. MBRO - muligheder • Server-activated object (SAO)også betegnet ”Wellknown objects” • Singleton: Ét serverobjekt til alle klienter • Trådproblemer • SingleCall: Ét objekt pr. metodekald • Nemmeste løsning; men mindst effektivt • Tilstand opretholdes vha. filer eller database • Client-activated object (CAO) • Activated: Ét objekt pr. klient • Levetidsproblem – Leasing understøttes ikke af IIS

  43. MBVO - muligheder • Egenudviklede klasser • Kan udføre special-opgaver på klienten • .NET collection og db-klasser • Eksempelvis DataSet er en meget brugbar klasse til at overføre data …

  44. Minimér udrulning på klienten • Hvad skal udrulles på klienten? • Som udgangspunkt: • Konkrete implementationer af alle MBRO- og MBVO-klasser • Dette vil vi som regel gerne minimere … • Mulige tilgange: • Definér MBRO vha. interfaces og udrul Interface.dll • Definér MBVO vha. .NET-klasser som fx DataSet

  45. Design - Server • Minimér antal kald fra klient til server, da: • Ethvert kald går via netværket • Ethvert kald er et potentielt nyt server-objekt • Ethvert kald involverer marshalling • Enhver reference til en property er også et kald • Svartider er uforudsigelige … • Retningslinjer: • Færre og større metoder • Metoder er transaktioner – Commit/Rollback før return

  46. Design - Klient • Anvend factory-klasser og .config-filen • Factory-klasser skjuler instantieringslogik • Konfigurationsfilen kan specificere URL, formattering, channels, osv. • Konfigurationsfilen kan redirigere new til at instantiere på serveren

  47. MathLibrary.dll namespace MathLibrary { public class SimpleMath : MarshalByRefObject{ private static int classCount = 0; private int instanceCount; public SimpleMath() { this.instanceCount = ++SimpleMath.classCount; } public int Add(int a, int b) { return a + b; } public int Sub(int a, int b) { return a - b; } public int Count { get { return this.instanceCount; } } } }

  48. SAO - Wellknown Objects namespace MathServer { class Program { static void Main(string[] args) { ChannelServices.RegisterChannel(new HttpChannel(20001), false); RemotingConfiguration.RegisterWellKnownServiceType(typeof(SimpleMath),"SimpleMath.soap",WellKnownObjectMode.SingleCall); } } } namespace MathKlient { class Program { static void Main(string[] args) {RemotingConfiguration.RegisterWellKnownClientType(typeof(SimpleMath),"http://localhost:20001/SimpleMath.soap");SimpleMath math = new SimpleMath(); } } }

  49. SAO – Activator.GetObject namespace MathServer { class Program { static void Main(string[] args) { ChannelServices.RegisterChannel(new HttpChannel(20001), false); RemotingConfiguration.RegisterWellKnownServiceType(typeof(SimpleMath),"SimpleMath.soap",WellKnownObjectMode.SingleCall); } } } namespace MathKlient { class Program { static void Main(string[] args) {ISimpleMath math = (ISimpleMath)(Activator.GetObject(typeof(ISimpleMath), "http://localhost:20001/SimpleMath.soap")); } } }

  50. Remoting gennem interface namespace IMathLibrary { public interfaceISimpleMath { int Add(int a, int b); int Sub(int a, int b); int Count {get;} } } namespace MathLibrary { public class SimpleMath : MarshalByRefObject, IMathLibrary.ISimpleMath private static int classCount = 0; private int instanceCount; public SimpleMath() {this.instanceCount = ++SimpleMath.classCount; } public int Add(int a, int b) {return a + b;} public int Sub(int a, int b) {return a - b;} public int Count { get { return this.instanceCount; } } } }

More Related