C# und Nichtsequentialität

Werbung
Seminar Ojektorientierte
Programmiersprachen
WS 2003/04
FU-Berlin
Dozent: Prof.Dr.-Ing.Peter Löhr
Vortrag
C# und Nichtsequentialität
( Polyphonic C# )
2
Polyphonic C#









C# vs Java
Definition
Beispiele
Spezifikation
Restriktion
Programming in Polyphonic C#
Implementation and Translation
Schlussfolgerung
Quelle
3
Blocksynchronization
(C# vs Java)
C# Code
public void WithdrawAmount(int num){
lock(this){
if(num < this.amount) this.amount -= num;
}}
Java Code
public void withdrawAmount(int num){
synchronized(this){
if(num < this.amount) this.amount -= num;
}}
4
MethodSynchronization
(C# vs Java)
C# Code
[MethodImpl(MethodImplOptions.Synchronized)]
public void WithdrawAmount(int n){
if(n < this.amount) this.amount - n;
}
Java Code
public synchronized void withdrawAmount(int n){
if(n < this.amount) this.amount - n;
}
5
Threads (C# vs Java )
Java
 Extending Java.lang.Thread
 Overriding run method
 Or implementing java.lang.Runnable
interface and its run method
 every class inherits the wait(), notify() and
notifyAll() from java.lang.Object
 Multithreaded „run methods“ designed up
front for multithreaded scenarios
6
Threads (C# vs Java )
C#
 creating a new System.Threading.Thread object
 passing it a System.Threading.ThreadStart
delegate
 Delegate initialized with the method that is to be run
as a thread
 any method can be passed to a ThreadStart object
and run in a multithreaded scenario
 Every class inherits Wait(), Pulse() and PulseAll()
methods in the System.Threading.Monitor
7
Einleitung

Asynchrone Nachrichten und Erreignisse



Benutzerschnittstellen- Treibererreignisse ,
verteilte Systeme , Web Services etc
Alle diese asynchrone Nachrichten werden
von Threads behandlet
Threads sind immernoch kostbare Resourcen
an vielen Systemen
Verstecken von Threads hinter
Sprachmechanismus
8
Einleitung

Nick Benton, Luca Cardelli und Cedric
Fournet bei Microsoft Research



Concurrency should be a language feature
High-level abstraction for asynchronous
programming
Hence better optimization possibilities for the
compiler

(queues, lightweight threads, thread pools)
9
Was ist nun Polyphnic C# ?


eine Erweiterung von C# mit neuen
asynchronen nichtsequentiallen Konstrukten
Basierend auf dem Join Calculus

Eine geignete Sprache für asynchron verteilten
Systemen
10
Was ist nun Polyphnic C# ?



Alle features von C# bleiben erhalten
Hinzufügen von zwei neuen
SprachKonstrukten
Asynchronous methods und Chords
11
Was ist nun Polyphnic C# ?




Standard Methoden sind alle synchron
Der Aufruf kehrt nach der Ausführung des
Rumpfs zurück
Asynchrone Methode haben async vor
Methodennamen
Kehren sofort ohne Rückgabewert zurück
12
Was ist nun Polyphnic C# ?
Chords
 Auch synchronization pattern oder join
pattern genannt
 Besteht aus Methodenkopf und
Methodenrumpf
 Der Kopf kann aus mehreren Methoden
bestehen
 Sie werden durch einen & getrennt
13
Was ist nun Polyphnic C# ?





In einem Chord kann es nur eine synchrone
Methode geben aber viele async
Ausführung des Rumpfs nur wenn alle Methoden
aufgerufen sind
Sonst wird der Thread in einer Schlange gestellt
Steht eine async Methode alleine, wird sie in einem
neuen Thread sofort ausgeführt
Eine Methode kann in vielen
Chords(synchronization patterns) auftauchen
14
Ein einfaches Beispiel
class Buffer {
String get() & async put(String s)
{
return s;
}
}
15
Ein einfaches Beispiel
class Buffer {
String get() & async put(String s)
{
return s;
}
}

Eine einfache paramterlose synchrone
Methode mit String Rückgabewert
16
Ein einfaches Beispiel
class Buffer {
String get() & async put(String s) {
return s;
}
}
 Eine einfache paramterlose synchrone Methode mit
String Rückgabewert
 Eine asynchrone Methode mit String-Parameter
(liefert keinen Wert Zurück)
17
Ein einfaches Beispiel
class Buffer {
String get() & async put(String s) {
return s;
}
}
 Eine einfache paramterlose synchrone Methode mit String
Rückgabewert
 Eine asynchrone Methode mit String-Parameter (liefert keinen
Wert Zurück)
 Beide in einem Chord (synchronization pattern)
18
Chords


Ein Object kann mehrere Chords enthalten
Welche Methode der passende Partner einer
anderen wird, ist unbestimmt
19
Beispiel mit zwei Chords
class Buffer {
int get() & async put(int n) {
return n;
}
string get() & async put(int n){
return n.ToString();
}
}

Welches put mit welchem get synchronisiert wird, ist
unbestimmt
20
Buffer buff
= new Buffer();
buff.put(‘‘blue“);
buff.put(‘‘sky“);
Console.Write(buff.get()+“ ‘‘+buff.get());


Ausgabe unbestimmt
‘‘blue sky“ oder auch ‘‘sky blue“
21
Informelle Spezifikation
Return-type
= type | void | async
chord-declaration
::= method-header | [&
method-header]* body
method-header
::= attributes modifiers
return-type member-name(formals)
22
Restriktion für Vererbung
Bei Überschreibung einer Methode eines
Chords einer Superklasse müssen alle
Methoden dieses Chords überschrieben
werden
 impliziert Transivität
23
Restriktion für Vererbung
class C {
virtual void f() & virtual async g(){ /* body1 */ }
virtual void f() & virtual async h(){ /* body2 */ }
class D:C {
override async g(){ /* body3 */ }
 Gefahr eines Deadlocks
24
Programming in Polyphonic C#



Reader-Writer Locks
Asynchrone Nachrichten
Active Objects
25
Reader-Writer Locks
public class ReaderWriter {
public 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(); }
}
26
Asynchrone Nachricht
public delegate async IntCB(int v);
public class Service {
public async request(String arg, IntCB callback) {
int result;
// do something interesting…
callback(result);
}
}
27
Asynchrone Nachricht
class Join2 {
void wait(out int i, out int j)
& async first(int r1)
& async second(int r2) {
i = r1; j = r2; return;
}
}
// client code:
int i,j;
Join2 x = new Join2();
service1.request(arg1, new IntCB(x.first));
service2.request(arg2, new IntCB(x.second));
// do something useful
// now wait until both results have come back
x.wait(out i,out j);
// do something with i and j
28
Active objects(1/2)
public abstract class ActiveObject {
protected bool done;
abstract protected void ProcessMessage();
public ActiveObject () {
done = false;
mainLoop();
}
async mainLoop() {
while (!done) { ProcessMessage(); }
}
}
29
Active objects(2/2)
class StockServer : ActiveObject {
private ArrayList clients;
public async AddClient(Client c) & void ProcessMessage(){
clients.Add(c);
}
public async WireQuote(Quote q) & void ProcessMessage(){
foreach(Client c in clients)
c.UpdateQuote(q);
}
public async CloseDown() & void ProcessMessage(){
done
= true;
}
}
30
Implementation and Translation
struct BitMask{
private int v; // = 0;
public void set(int m) {v |= m; }
public void clear(int m) { v &= ~m; }
public bool match(int m ) { return ( ~v & m)==0; }
}
class intQ {
private Queue q;
public intQ() {q = new Queue(); }
public void add(int i) { q.Enqueue(i); }
public int get() {return (int) q.Daqueue(); }
public bool empty {get{return q.Count == 0;}}
}
31
Implementation and Translation
class voidQ{
private int n;
public voidQ() { n = 0; }
public void add() { n++; }
public void get() { n--; }
public bool empty {get{ return n==0; }}
}
32
Implementation and Translation
class threadQ {
private Queue q;
public threadQ() { q = new Queue(); }
public bool empty {get{ return (q.Count == 0); }}
public void yield(object myCurrentLok){
q.Enqueue(Thread.CurrentThread);
Monitor.Exit(myCurrentLock);
try {
Thread.Sleep(Temeout.Infinite);
}
catch (ThreadInterruptedException) {}
Monitor.Enter(myCurrentLock;
q.Dequeue();
}
public void wakeup() {((Thread) q.Peek()).Interrupt();}
}
33
Eine Polyphonic-klasse
Class Token{
public Token(int initialToken){
for(int i=0;i<initialTokens;i++)Release();
}
public int Grab(int id) & public async Release(){
return id;
}
}
34
Die kompilierte Klasse(1/3)
class Token{
private const int mGrab = 1 << 0;
private const int mRelease = 1 << 1;
private threadQ GrabQ = new threadQ();
private voidQ ReleaseQ = new voidQ();
private const int mGrabRelease
= mGrab |
mRelease;
private BitMask s
= new BitMask();
private object mlock = GrabQ();
35
Die kompilierte Klasse(2/3)
..................
private void scan(){
if(s.match(mGrabRelease)) GrabQ.wakeup();
}
public Token(int initialTokens){
for(int i=0;i< initialTokens;i++)Release();
}
[OneWay]
public void Release(){
lock(mlock){
ReleaseQ.add(),
if(!s.match(mRelease)){
s.set(mRelease);
scan();
}
}
}
36
Die kompilierte Klasse(3/3)
...........................
public int Grab(int id){
Monitor.Enter(mlock);
if( !s.match(mGrab) )goto now;
later:
GrabQ.yield(mlock);if(GrabQ.empty) s.clear(mGrab);
now:
if(s.match(mRelease)){
ReleaseQ.get();
if(ReleaseQ.empty)s.clear(mRelease);
scan();
Monitor.Exit(mlock);
{
return id; //source code for the chord
}
}else{s.set(mGrab);goto later;}
}
}
37
Fully Asynchronous Chords
..............
public async live(string s,int id){
Grab(id);
Release();
Console.WriteLine(s);
}
38
Translated Fully Asynchronous Chord
private class liveArgs{
public string s;public int id;
public liveArgs(string s,int id){
this.s= s;this.id=id;
}
}
private void liveBody(object o){
liveArgs a = (liveArgs)o;
string s = a.s;int id= a.id;
Grab(id);Release();
Console.WriteLine(s);
}
39
Translated Fully Asynchronous Chord
...........
[OneWay]
Public void live(string s,int id){
liveArgs a = new lineArgs(s,id);
WaitCallback c = new WaitCallback(liveBody);
ThreadPool.QueueUserWorkItem(c,a);
}
}
40
Future Work


Concurrency Types
Timeouts and Priorities



Optimizations




Declarative support for timeouts or priorities
Finer control over dynamic scheduling
Lock optimization
Queue optimization
Thread optimization
Pattern-Matching

Additional constraints in arguments
41
Schlussfolgerung


Ein sauber und einfaches Modell für
asynchrone Nichtsequentiallität in C#
Modell geignet für



Lokale Nichtsequentiallität (viele Threads auf
einer Maschine )
Verteilte Nichtsequentiallität ( asynchrone
Erreignisse über LAN oder WAN )
Kompatible mit existierenden Konstrukten
42
Polyphonic C#
Dining Philosophers Demo
Copyright (C) 2001 Microsoft Corporation
43
Quellen:

Introduction to Polyphonic C#
http://research.microsoft.com/~nick/polyphony/intro.htm

Modern Concurrency Abstractions for C#
(Nick Benton, Luca Cardelli, and C´edric Fournet)
http://research.microsoft.com/~nick/polyphony/PolyphonyECOOP.A4.pdf
44
Herunterladen