1 / 70

Concurrency in C 

Concurrency in C . Nick Benton. Luca Cardelli Nick Benton Karthik Bhargavan Gavin Bierman Byron Cook C é dric Fournet Georges Gonthier Andy Gordon. Tony Hoare Andrew Kennedy Simon Marlow Simon Peyton Jones Claudio Russo Don Syme + visitors. PPT: People. Exciting Times….

elina
Download Presentation

Concurrency in C 

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. Concurrency in C Nick Benton

  2. Luca Cardelli Nick Benton Karthik Bhargavan Gavin Bierman Byron Cook Cédric Fournet Georges Gonthier Andy Gordon Tony Hoare Andrew Kennedy Simon Marlow Simon Peyton Jones Claudio Russo Don Syme + visitors PPT: People

  3. Exciting Times… • C# and Java are strongly typed, garbage collected languages with language-level security mechanisms • this was the preserve of academic languages ten years ago! • Parametric polymorphism in C# 2.0 and Java 5 • Mixed-language programming is really happening • Concurrency is going mainstream • Using advanced analysis tools for finding bugs and checking correctness properties is becoming routine • Contracts and behavioural types are hot topics • Only go back ten years in academia • Security matters

  4. PPT: Some Other Projects • Generics for C# and Microsoft® .NET • SML.NET, Haskell, F# • Stack-walking Security in .NET • Formal Tools for Securing Web Services • Query Languages for Semi-structured Data • First-class Functions for Microsoft® Excel • Languages for Systems Biology • Software Transactional Memory

  5. Why Cw? • Target domain: distributed Web applications • Common “three tier” architecture: • Data services tier (database) • Middle tier (main application) – C#/Java • User interface tier (XML/HTML) • Concurrency scenario: asynchronous events and message passing • Web services, workflow orchestrations, …

  6. The Reality • It’s about both • DATA • Objects, XML, relations • CONTROL • Asynchrony, concurrency • Even though our languages are “modern”, support for these features is pretty primitive • Data access is weakly typed, mostly string based • Control uses concepts from the ’60s (Monitors, etc.) • Essence: these important features are left to APIs 

  7. The Guiding Principle • Provide better level of abstraction • Make invariants and intentions more apparent (part of the interface) • Give stronger compile-time guarantees (types) • Enable different implementations and optimizations • Expose structure for other tools to exploit (example: static analysis) Put (really) important features in the language itself, rather than in libraries

  8. The CProject in a Slide • We’re building an experimental language with • C# at its core • First-class support for common data models • A better model of concurrency for both local and distributed concurrency • Second principle: RISCy language extension • Don’t bake complex solutions into language • Choose minimal pieces from which solutions can be built • Those pieces having already been shown effective in `purer’ more academic settings • Impedance match to new setting (and even user profile)

  9. Cw Data (very briefly) • New types: • Streams (T*) • Choice (choice{int;string;}) • Tuples (struct{int i;string s;}) • Content classes • Nullables (T?) • Minimal extensions to allow (fairly) high fidelity, strongly typed, mapping of both relational and semistructured data • XML literals (OK, so that’s not very RISCy) • Generalized member access (cf. XPath) • SQL-style selectqueries

  10. But today’s topic is… Concurrency

  11. Asynchrony Is Where It’s At • Distribution → concurrency + latency → asynchrony→ more concurrency • Message-passing, event-based programming, dataflow models • For programming languages, coordination (orchestration) languages and frameworks, workflow

  12. .NET Today • Java-style “monitors” • Operating system shared memory primitives • Clunky delegate-based asynchronous calling model • Hard to understand, use and get right • Different models at different scales • Support for asynchrony all on the caller side – little help building code to handle messages (must be thread-safe, reactive, and deadlock-free)

  13. CConcurrency • New concurrency model and language constructs • Based on the join calculus • A foundational process calculus like the p-calculus but better suited to asynchronous, distributed systems • A single model which works both for • local concurrency (multiple threads on a single machine) • distributed concurrency (asynchronous messaging over LAN or WAN) • It is different • But it’s also simple

  14. C Concurrency in One Slide • Objects have both synchronous and asynchronous methods • Values are passed by ordinary method calls: • If the method is synchronous, the caller blocksuntil the method returns some result (as usual) • If the method is async, the call completes at once and returns void • A class defines a collection of chords (synchronization patterns), which define what happens once a particular set of methods have been invoked. One method may appear in several chords. • When pending method calls match a pattern, its body runs. • If there is no match, the invocations are queued up. • If there are several matches, an unspecified pattern is selected. • If a pattern containing only async methods fires, the body runs in a new thread.

  15. A Simple Buffer(for use by producer/consumer threads) class Buffer { async put(string s); stringget() & put(string s) { return s; } }

  16. A Simple Buffer class Buffer { async put(string s); stringget() & put(string s) { return s; } } • An ordinary (synchronous) method with no arguments, returning a string • An ordinary (synchronous) method with no arguments, returning a string

  17. A Simple Buffer class Buffer { async put(string s); stringget() & put(string s) { return s; } } • An ordinary (synchronous) method with no arguments, returning a string • An asynchronous method (hence returning no result), with a string argument

  18. A Simple Buffer class Buffer { async put(string s); stringget() & put(string s) { return s; } } • An ordinary (synchronous) method with no arguments, returning a string • An asynchronous method (hence returning no result), with a string argument • Joined together in a chord

  19. A Simple Buffer class Buffer { async put(string s); stringget() & put(string s) { return s; } } • Calls toput()return immediately, but are internally queued if there’s no waitingget() • Calls toget()block until/unless there’s a matchingput() • When there’s a match the body runs, returning the argument of theput()to the caller ofget() • Exactly which pairs of calls are matched up is unspecified

  20. A Simple Buffer class Buffer { async put(string s); stringget() & put(string s) { return s; } } • Does this example involve spawning any threads? • No. Though the calls will usually come from different pre-existing threads. • Is it thread-safe? You don’t seem to have locked anything… • Yes. The chord compiles into code which uses locks. (And that doesn’t mean everything is synchronized on the object.) • Which method gets the returned result? • The synchronous one; there is at most one of these in a chord.

  21. Reader/Writer …using threads and mutexes in Modula 3 An introduction to programming with threads Andrew D. Birrell, January 1989

  22. Reader/Writer in Five Chords publicclass ReaderWriter { privateasync idle(); privateasync s(int n); public ReaderWriter() {idle();} publicvoid Exclusive() & idle() {} publicvoid ReleaseExclusive() { idle(); } publicvoid Shared() & idle() { s(1);} & s(int n) { s(n+1);} publicvoid ReleaseShared() & s(int n) { if (n == 1) idle(); else s(n-1); } } A single private message represents the state: none↔idle()↔s(1) ↔s(2) ↔ s(3) …

  23. Asynch Requests/Responses • Service exposes an async method which takes parameters and somewhere to put the result: • a buffer, or a channel, or • here, an asynchronous delegate, used as a callback publicdelegateasync IntCB(int v); // the callback publicclass Service { publicasync request(String arg, IntCB callback){ … // compute result callback(result); // respond! } }

  24. Joining Responses class Join2 { async first(int r); async second(int r); struct{int;int;} waitAll() & first(int r1) & second(int r2) { returnnew{r1,r2}; } } // client code: struct{int;int;} results; Join2 x = new Join2(); service1.request(arg1, new IntCB(x.first)); service2.request(arg2, new IntCB(x.second)); // do something useful in the meantime // now wait until both results have come back results = x.waitAll(); // do something with results

  25. Selecting Responses class Select2 { async reply(int r); int waitOne() & reply(int r) { return r; } } // client code: int result; Select2 x = new Select2(); service1.request(arg1, new IntCB(x.reply)); service2.request(arg2, new IntCB(x.reply)); // do something useful in the meantime // now wait until one result has come back result = x.waitOne(); // do something with result

  26. Active Objects publicabstractclass ActiveObject : MarshalByRefObject { protectedbool done; abstractprotectedvoid processmessage(); public ActiveObject () { done = false; mainloop(); } async mainloop() { while (!done) { processmessage(); } } }

  27. …continued class Stock : ActiveObject { publicasync bid(BidOffer thebid); publicasync register(Client who); overrideprotectedvoid processmessage() & bid(BidOffer thebid) { // process bid messages } & register(Client who) { // process registration requests } … }

  28. Extending C# with chords • Syntax extensions: • Declarations for asynchronous methods • Definitions of (synchronous) methods generalized to chord definitions • when for purely asynchronous chords • Interesting well-formedness conditions: • Can’t have two synchronous methods in a single pattern • The inheritance restriction • “ref” and “out” parameters cannot appear in async headers

  29. Why ≤1 synchronous method in a chord? • JoCaml allows multiple synchronous methods to be joined, as in the following rendezvous • But in which thread does the body run? In C#, thread identity is “very” observable, since threads are the holders of particular re-entrant locks. So we rule this out in the interests of keeping & commutative. (Of course, it’s still easy to code up an asymmetric rendezvous in Polyphonic C#.) int f(int x) & int g(int y) { return y to f; return x to g; }

  30. The problem with inheritance class C { virtualasync g(); virtualasync h(); virtualvoid f() & g() {…} & h() {…} } class D : C { overrideasync g(); } • We’ve “half” overridden f • Too easy to create deadlock or async leakage void m(C x) { x.g(); x.f();} … m(new D());

  31. The inheritance restriction • Two methods are co-declared if there’s a chord with both of them in Whenever a method is overridden,every co-declared method must also be overridden • privateasync g() • publicvirtualvoid f() & g() {…} • Inheritance and concurrency don’t mix well.Our restriction is simple; it could be made less restrictive.

  32. Types etc. • async is a subtype of void • Allow covariant return types on those two: • An async method may override a void one • A void delegate may be created from an async method • An async method may implement a void method in an interface • async methods are given the [OneWay] attribute, so remote calls are non-blocking

  33. Implementation • 4th version… • Built on CCI (also used for Spec#), runs in VS • Introduce queues for pending calls (holding blocked threads for sync methods, arguments for asyncs) • Generated code (using brief lock to protect queue state) looks for matches and then either • Enqueues args (async no match) • Enqueues thread and blocks (sync no match) • Dequeues other args and continues (sync match) • Wakes up blocked thread (async match with sync) • Spawns new thread (async match all async) • Efficient – bitmasks to look for matches, no PulseAlls,… • We’ve changed the underlying implementation to match changes in CLR performance (sleeping/interrupting -> waiting/pulsing)

  34. Predictable Demo: Dining Philosophers waiting to eat eating waiting to eat thinking eating

  35. Code Extract class Room { privateasync hasspaces(int n); privateasync isfull(); public Room (int size) { hasspaces(size); } publicvoid enter() & hasspaces(int n) { if (n > 1) hasspaces(n-1); else isfull(); } publicvoid leave() & hasspaces(int n) { hasspaces(n+1); } & isfull() { hasspaces(1); } }

  36. Demonstration Dining philosophers

  37. Other Samples • Web service combinators (Cardelli & Davies) • Adaptive scheduler (cf. Larus & Parkes), • Accessing web services (Terraserver), • Active objects and remoting (stock trader) • Santa Claus problem (Trono)

  38. Influence • 3 internal projects use joins of some form • External • MC# • Nemerle • QUT web service language • Spry

  39. Current and future work • Extension with generics • Limited pattern-matching on message contents • Been prototyped (Melgratti) but very hard to compile efficiently • Direct syntactic support for timeouts along this line would be nice… • Adding joinable transactions with explicit compensations (Bruni, Montanari) • Behavioural types • Integration/compilation with STM???

  40. Summary • A clean, simple, new model for asynchronous concurrency in C# • Declarative, local synchronization • Model good for both local and distributed settings • Efficiently compiled to queues and automata • Easier to express and enforce concurrency invariants • Compatible with existing constructs, though they constrain our design somewhat • Minimalist design – pieces to build whatever complex synchronization behaviours you need • Solid foundations • Works well in practice

  41. Compiler Release • Freely available (v.1.0.2) from http://research.microsoft.com/comega • Over 7000 downloads so far  • Please download and play!

  42. For More Information • http://research.microsoft.com/comega • Papers, compiler, links • http://channel9.msdn.com/ ShowPost.aspx?PostID=23947 • Channel 9 video • http://www.omegaengine.com/ • A public discussion forum • Not run by Microsoft/Microsoft Research

  43. Credits Nick Benton Gavin Bierman Luca Cardelli Cédric Fournet Erik Meijer Claudio Russo Wolfram Schulte Herman Venter Mark Shinwell, Hernan Melgratti, and all the other folks who’ve contributed to the implementation

  44. Questions?

  45. One-shot TimeoutBuffer class TimeoutBuffer { async empty(); async has(Object o); async timeout(); TimeoutBuffer(int delay) { Timer t = new Timer(new TimerCallBack(this.tick),delay); empty(); } void put(Object o) & empty() {has(o);} & timeout() {timeout();} void tick() & empty() {timeout();} & has(Object o) {has(o);} Object get() & timeout() {timeout(); throw new TimeOutExn();} & has(Object o) {has(o); return o;} }

  46. Fairer reader/writer lock class ReaderWriterFair { ReaderWriter() { idle(); } private int n = 0; // protected by s() or t() public void Shared() & async idle() { n=1; s(); } public void Shared() & async s() { n++; s(); } public void ReleaseShared() & async s() { if (--n == 0) idle(); else s(); } public void Exclusive() & async idle() {} public void ReleaseExclusive() { idle(); } public void ReleaseShared() & async t() { if (--n == 0) idleExclusive(); else t(); } public void Exclusive() & async s() { t(); wait(); } void wait() & async idleExclusive() {} }

  47. Queries stored as strings Weak Type Using string to project attributes Runtime type conversion Current Data Access in C# SqlConnection conn = new SqlConnection(…); conn.Open(); Console.WriteLine("Please enter a city: "); string input = Console.ReadLine(); SqlCommand cmd = new SqlCommand("SELECT * FROM Customers WHERE city='"+input+"'", conn); SqlDataReader results = cmd.ExecuteReader(); Console.WriteLine("Customers from: "+input); while (results.Read()) { string Name = (string)results["ContactName"]; string Phone = (string)results["Phone"]; Console.WriteLine(Name + " -- "+Phone); } conn.Close();

  48. API Access (Continued) • Storing queries as strings is not only ugly but also a security risk • Imagine where city=“’ OR 1=1 --” • This will return the entire relation!! • This is the source of many security loopholes in Web-based databases

  49. Use Parameters and Typed Datasets… SqlDataAdapter da = new SqlDataAdapter( "SELECT * FROM Customers WHERE City= @city", conn ); SqlParameter cityParam = da.SelectCommand.Parameters.Add("@city", SqlDbType.VarChar, 80); cityParam.Value = input; NorthwindDataSetds = new NorthwindDataSet(); da.Fill(ds,ds.Customers.TableName); foreach (NorthwindDataSet.CustomersRow dr inds.Customers.Rows) { string Name =dr.ContactName; string Phone =dr.Phone; Console.WriteLine( Name + " -- " + Phone); }

  50. Or Use Stored Procedures… CREATE PROCEDURE CustomersForCity @City nvarchar(80) AS SELECT * FROM Customers WHERE City = @City SqlCommand cmd = new SqlCommand("dbo.CustomersForCity",conn ); cmd.CommandType = CommandType.StoredProcedure; SqlParameter cityParam = cmd.Parameters.Add("@City", SqlDbType.VarChar, 80); cityParam.Value = input; SqlDataAdapter da = new SqlDataAdapter( cmd ); NorthwindDataSet ds = new NorthwindDataSet(); da.Fill(ds, ds.Customers.TableName ); foreach (NorthwindDataSet.CustomersRow dr in ds.Customers.Rows) { string Name =dr.ContactName; string Phone =dr.Phone; Console.WriteLine( Name + " -- " + Phone); }

More Related