0% found this document useful (0 votes)
60 views43 pages

Modern Concurrency Abstractions For C#

The document summarizes a presentation on concurrency abstractions in C#. It discusses concurrency in modern code, how it affects programming languages, and asynchronous programming. It then focuses on features in C# like threads, events, and locks for concurrency. Polyphonic C# is introduced as adding asynchronous methods and chords to provide concurrency in a safer way than traditional approaches. Examples demonstrate using chords for thread-safe buffers and rendezvous.

Uploaded by

Muhammad Kamran
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
60 views43 pages

Modern Concurrency Abstractions For C#

The document summarizes a presentation on concurrency abstractions in C#. It discusses concurrency in modern code, how it affects programming languages, and asynchronous programming. It then focuses on features in C# like threads, events, and locks for concurrency. Polyphonic C# is introduced as adding asynchronous methods and chords to provide concurrency in a safer way than traditional approaches. Examples demonstrate using chords for thread-safe buffers and rendezvous.

Uploaded by

Muhammad Kamran
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 43

Modern Concurrency

Abstractions for C#

presented by: Guy Gueta

Advanced Software Tools Seminar


December, 2004
Agenda
Concurrency
Concurrency and Languages
Asynchronous Programming
C# and .NET
Polyphonic C#
Examples
Performance
Concurrency
Concurrency is widely used in modern
code
It is very difficult to write/debug concurrent
programs
Concurrency
Can affect the ability to invoke libraries
strtok(….) / Rand() & SRand(….)
Can significantly affect the meaning of virtually
every construct in the language
X++ ;
X=Y;
Most popular programming languages treat
concurrency not as a language feature, but as a
collection of external libraries
Language Features / Libraries
Many features can be provided either as
language features or as libraries
– Memory management
– Exceptions
– Locks
The compiler can analyze language features
– Can produce better code (e.g. local new)
– Can warn programmers of potential and actual
problems.
Polyphonic C#
Example: Monitor
The concept of monitors [Hoare 1974]
The general notion of monitors has
become very popular
public synchronized void Add(int v)
{
// body
}

public synchronized int Get(int v)


{
// body
}

wait()/notify()
Asynchronous Programming
Asynchronous events and message
passing are increasingly used at all
levels of software systems
e.g. Distributed Applications/components,
GUI, Device Drivers
Many asynchronous messages should be
handled concurrently. Many threads are
used to handle them
Polyphonic C#
C# and .NET
Modern, type-safe, object-oriented
programming language
Very similar to Java
C# programs run on top of the .NET
Framework, which includes a multi-
language execution engine and a rich
collection of class libraries.
– .NET IL
JAVA C#

public class Point { public class Point {


protected int x, y; protected int x, y;

public Point() public Point()


{ setPoint( 0, 0 ); } { setPoint( 0, 0 ); }

public Point( int a, int b ) public Point( int a, int b )


{ setPoint( a, b ); } { setPoint( a, b ); }

public void setPoint( int a, int b ) public void setPoint( int a, int b )
{ {
x = a; x = a;
y = b; y = b;
} }

public int getX() { return x; } public int getX() { return x; }


public int getY() { return y; } public int getY() { return y; }
} }
Concurrency in .NET
Threads
Sync. Event (Semaphore, Mutex)
Reader/writer lock
Asynchronous programming model based
on delegates
lock (C#)
Polyphonic C#

Adds just two new concepts: asynchronous


methods and chords
Synchronous Methods
Regular C# methods
The caller makes no progress until the
callee completes
Asynchronous Method
Any call to it is guaranteed to complete
essentially immediately
Never returns a result (or throws an exception)
calling it is much like sending a message, or
posting an event
declared by using the async keyword instead of
void
public async postEvent(EventInfo data)
{
// large method body
}

Usually defined using chords –


do not necessarily require new threads
Chord
A set of method declarations separated
by ‘&’ And a body.

public string Foo1() & public async Foo2(string s1) &


public async Foo3(string s2) & private async Foo4(string s3)
{
// Body
}

At most one method may be synchronous.


Return Value type = Synchronous method type
Chord
public async Foo1() & public async Foo2(string s1) &
public async Foo3(string s2) & private async Foo4(string s3)
{
…..
}

public string Foo1() & public async Foo2(string s1) &


public async Foo3(string s2) & private async Foo4(string s3)
{
…..

return myString;
}
Trivial Chord = Regular method
public class Buffer
{
public string Get() & public async Put(string s) { return s; }
}
Chord
Thread 1 Thread 2
Put(“1”)
b.Put(“1”); Writeln(b.Get()); Get()
Writeln(b.Get()); b.Put(“2”); Put(“3”)
Writeln(b.Get()); b.Put(“3”);
b.Put(“4”); Writeln(b.Get());

OUTPUT:
1
2
3
4
Buffer buff = new Buffer();
buff.Put(“blue”);
buff.Put(“sky”);
Console.Write(buff.Get());
Console.Write(buff.Get());

bluesky
skyblue

[In a real implementation the nondeterminism may be resolved]


Thread safety
The chord mechanism is thread safe
– The locking that is required is generated automatically
by the compiler
– deciding whether any chord is enabled by a call and,
if so, removing the other pending calls from the
queues and scheduling the body for execution, is an
atomic operation.
no monitor-like mutual exclusion between chord
bodies
Any mutual exclusion that is required must be
explicitly programmed in terms of
synchronization conditions in chord headers
A Simple Cell Class
public class OneCell
{
public OneCell()
{
empty();
}
public void Put(object o) & private async empty()
{
contains(o);
}
public object Get() & private async contains(object o)
{
empty();
return o;
}
}
One method in multiple chords
It is possible (and common) to have multiple
chords involving a given method

public class Buffer


{
public string Get() & public async Put(string s)
{
return s;
}
public string Get() & public async Put(int n)
{
return n.ToString();
}
}
nondeterminism
Within a single method-header
public void AddOne(ref int a) public void Random(out int a)
{ {
a++; a = ….
} }

Int x = 7; Int a ;
AddOne(ref x); Random(out a);

If return-type is async then the formal


parameter list formals may not contain any
ref or out parameter modifier
Within a single chord-declaration
At most one method-header may have a
non-async return-type
If the chord has a method-header with
return-type type, then body may use
return statements with type expressions,
otherwise body may use empty return
statements
All the formals appearing in method-
headers must have distinct identifiers
Within a single chord-declaration –
cont’
Two method-headers may not have both
the same member-name and the same
argument type signature
The method-headers must either all
declare instance methods or all declare
static methods
Within a particular class
All method-headers with the same
member-name and argument type
signature must have the same return-type
and identical sets of modifiers

public string Get() & public async Put(string s)


{
return s;
}
private int Get() & public async Put(int n)
{
return n.ToString();
}
struct/class
struct ST class CL
{ {
public int x ; public int x ;
} }

public void foo() public void foo()


{ {
ST s1,s2 ; CL c1,c2 ;
s1.x = 7 ; c1 = new CL() ;
s2 = s1 ; c1.x = 7 ;
s1.x = 18 ; c2 = c1 ;
…. c1.x = 18 ;
} ….
}
Within a particular class – cont’
If it is a value class (struct), then only
static methods may appear in non-trivial
chords
virtual-override
Class A Class B : A
{ {
public void foo1() public override void foo2()
{ {
….
….
}
}
}

public virtual void foo2()


{
….
}
}
class C
{
public virtual void f () & public virtual async g() { /∗ body1 ∗/ }

public virtual void f () & public virtual async h() { /∗ body2 ∗/ }


}

class D : C
{
public override async g() { /∗ body3 ∗/ }
}

class E
{
public virtual void f() & private async g() { /∗ body4 ∗/ }
}
Within a particular class – cont’
If any chord-declaration includes a virtual
method m with the override modifier, then
any method n that appears in a chord with
m in the super class containing the
overridden definition of m must also be
overridden in the subclass
RendezVous
class RendezVous
{
private class Thunk
{
int wait() & async reply(int j ) {return j ;}
}
public int f (int i)
{
Thunk t = new Thunk();
af (i, t);
return t.wait();
}
private async af (int i, Thunk t) & public int g(int j )
{
t . reply( j ); // returning to f
return i; // returning to g
}
}
ReaderWriter 1
class ReaderWriter
{
ReaderWriter() {idle();}

public void Shared() & async idle() {s(1); }


public void Shared() & async s(int n) {s(n + 1); }
public void ReleaseShared() & async s(int n)
{
if (n == 1) idle(); else s(n − 1);
}
public void Exclusive() & async idle() {}
public void ReleaseExclusive() { idle(); }
}
ReaderWriter 2
class ReaderWriter
{
ReaderWriter() { idle(); }
private int n = 0; // protected by s()

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(); }
}
class ReaderWriterFair
{
ReaderWriter() { idle(); }
private int n = 0; // protected by s()

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() {}
}
Delegate

delegate bool MyDlg(string s,int I);

MyDlg d = new MyDlg(MyObj.f);


d(“Hello”, 7);
async & void

async is a subtype of void


– A void delegate may be created from an
async method
– An async method may override a void one
– An async method may implement a void
method in an interface
Combining Asynchronous
Messages

public delegate async IntCallback(int result);

public class Service


{
public async Request(string arg, IntCallback cb)
{
int r ;
. . . // do some work
cb(r); // send the result back
}
}
class Client {
public static void Main(string[] args) {
Service s1 = . . . ;
Service s2 = . . . ;
Join2 x = new Join2();
s1.Request(args[0], x . firstcb);
s2.Request(args[1], x . secondcb);
. . . // do something useful in the meantime. . .
int i, j ;
x.wait(out i, out j ); // wait for both results to come back
. . . // do something with them
}
}
class Join2
{
public IntCallback firstcb;
public IntCallback secondcb;

public Join2()
{
firstcb = new IntCallback(first);
secondcb = new IntCallback(second);
}

public void wait(out int i, out int j ) & async first(int fst)
& async second(int snd)
{
i = fst; j = snd;
}
}
Active Objects
public abstract class ActiveObject {

protected bool done;

abstract protected void ProcessMessage();

public ActiveObject () {
done = false;
mainLoop();
}

async mainLoop() {
while (!done) ProcessMessage();
}
}
public class StockServer : ActiveObject {

public async AddClient(Client c) // add new client


& override protected void ProcessMessage() {
// Body
}

public async CloseDown() // request to terminate


& override protected void ProcessMessage() {
done = true;
}
}
Remarks on Concrete Syntax
class ReaderWriter {
private async idle(); // Just signatures. Any modifiers or
private async s(int); // attributes would occur here too

public ReaderWriter() { idle(); }

public void Shared()


when idle() { s(1); }
when s(int n) { s(n + 1); }

public void ReleaseShared()


when s(int n) { if (n == 1) idle(); else s(n − 1); }

public void Exclusive()


when idle() {}
….
References
Modern Concurrency Abstractions for C#.
NICK BENTON, LUCA CARDELLI, and
CEDRIC FOURNET. Microsoft Research.
Applied Microsoft .NET Framework Programming.
Jeffrey Richter. Microsoft Press.
Java: How to Program, 4th ed. H.M. Deitel, P.J.
Deitel. Prentice Hall, 2002.
Monitors: An operating system structuring
concept. HOARE, C. A. R. 1974. Comm. ACM 17, 10
(Oct.), 549–557.
Thread Synchronization Fairness in the .NET CLR.
Jeffrey Richter. 2003.

You might also like