Lambda the Ultimate

inactiveTopic Modern Concurrency Abstractions for C#
started 4/30/2002; 9:36:11 PM - last post 5/3/2002; 10:44:45 AM
Chris Rathman - Modern Concurrency Abstractions for C#  blueArrow
4/30/2002; 9:36:11 PM (reads: 3266, responses: 5)
Modern Concurrency Abstractions for C#
This is a paper from Luca Cardelli & company at Microsoft Research that proposes the C# language extension of Polyphonic C#. It offers up some modifications to C# to provide "asynchronous concurrency constructs, based on the join calculus".

We believe that concurrency should be a language feature and part of language specifications. Serious attempts in this direction were made beginning in the 1970's with the concept of monitors and the Occam language. The general notion of monitors has become very popular, particularly in its current object-oriented form of threads and object-bound mutexes, but it has been provided at most as a veneer of syntactic sugar for optionally locking objects on method calls.

From the looks of it, the solution is not too invasive on the language, offering up only two new language constructs - Asynchronous Methods and Chords. Async methods resemble (and are partially interchangeable) with void functions (i.e. procedures). The function returns immediately - with no result - and continues processing in a seperate thread. Chords are a combination of a normal method with an async method, providing a method to join with an async method - both are declared together to syntactically bind the methods.
Posted to OOP by Chris Rathman on 4/30/02; 9:42:22 PM

Ehud Lamm - Re: Modern Concurrency Abstractions for C#  blueArrow
4/30/2002; 11:44:08 PM (reads: 2183, responses: 0)
I gave a link to this paper a few weeks ago. Maybe this time other will want to comment.

Chris Rathman - Re: Modern Concurrency Abstractions for C#  blueArrow
5/2/2002; 7:25:18 AM (reads: 2114, responses: 1)
I had it bookmarked - Probably from when you posted the link. :-)

Looking at the buffer example, Polyphonic C# would rendezvous the input and output as:

class Buffer { 
   string Get() & async Put(string s) { 
      return s;
   }
}

I gather from my intro book that the equivalent in Ada would be:

task BUFFERING is
   entry PUT(X: in STRING);
   entry GET(X: out STRING);
end;

task body BUFFERING is V: STRING; begin loop accept PUT(X: in STRING) do V := X; end PUT; accept GET(X: out STRING) do X := V; end GET; end loop; end BUFFERING;

I can see why the Ada solution would be much more flexible in the control over the process. But the Polyphonic C# does seem to have a certain attraction in it's simplicity. It also formally ties the two methods together formally - which I suppose could be used for some sort of static analysis.

Then again, my limited exposure to heavy use of threading, tasking, and distributed computing leans towards processes that are not one-to-one. The rendezvous usually involves waiting on a dynamic number of tasks - where a counting semaphore is more appropriate than a setEvent and getEvent combination.

Ehud Lamm - Re: Modern Concurrency Abstractions for C#  blueArrow
5/2/2002; 9:08:54 AM (reads: 2169, responses: 0)
It formally ties the two methods together formally - which I suppose could be used for some sort of static analysis.

That's what appealed to me too.

The problem is, I don't find the noatation easy to understand. For example, I am not sure if the Polyphonic C# example you give allows the sequence of operations Put, Put, Get? The Ada code you gave only alloaws (Put,Get)*.

One more thing. Ada tasks direclty communicate using rendezvous (which is one-to-one), but Ada also support protected objects which are extended monitors. These allow multile readers for example, and allow building various interesting and important synchronization objects (e.g., Brodcasts).

Chris Rathman - Re: Modern Concurrency Abstractions for C#  blueArrow
5/2/2002; 10:44:28 AM (reads: 2103, responses: 0)
The problem is, I don't find the noatation easy to understand. For example, I am not sure if the Polyphonic C# example you give allows the sequence of operations Put, Put, Get? The Ada code you gave only alloaws (Put,Get)*.
An Asynchronous method by itself will spin a new thread when the method is invoked. So if I had:

async Put(string s) {
   Console.WriteLine("Hello Put");
}

The call to Put would return immediately and a new thread would be created that processed the Hello.

In the case of Chords, however, the call to Put will not generate a new thread process. It also won't process any of the commands within the defined method. It's like the Chord is little more than a buffer of messages (parameters) which are queued up against the sister method. Chords do not invoke a function nor do they create threads. From the original example,

string Get() & async Put(string s) { 
   Console.WriteLine("Hello Get");
}

In this example, you could call Put a gazillion times, and it will not result in hello. Only when Get is called will the Hello run (and then only if at least one Put was called). The Chord causes the Get function to wait on a Put operation, but the method is really only run when the Get method is invoked.

I suppose it might have been more obvious had the async keyword not been used in two different ways - perhaps calling the second one a chord.

One more thing. Ada tasks direclty communicate using rendezvous (which is one-to-one), but Ada also support protected objects which are extended monitors. These allow multile readers for example, and allow building various interesting and important synchronization objects (e.g., Brodcasts).
No doubt that the Ada framework provides a lot more flexibility. The Polyphonic C# has the advantage of being simple in it's current form, but it could get bogged down in complexity real quick if they try to open it up much more.

Noel Welsh - Re: Modern Concurrency Abstractions for C#  blueArrow
5/3/2002; 10:44:45 AM (reads: 2069, responses: 0)
I can't read the document (Acrobat doesn't like it) but from the discussion above it sounds a bit suspect to me. One practical problem is that most thread implementations (sans Erlang) don't scale to a large number of threads so you don't want to go around creating threads at will. I'm not sure I like mixing concurrency into the rest of the mess that makes up an object (but that probably says more about what I think about OO than the concept).