Channels and GoRoutines in AjSharp (Part 2)

In my previous post I described the implementation of channels and goroutines-alike in AjSharp, my scripting language interpreter. I want to show some short examples using such features.

First, remember the simple code:

channel = new Channel();
go channel <- 10;
result = <- channel;

At first line, the channel is created. Then, go command runs in another thread, sending a value to the channel. The last line, running in initial thread, gets the value from the channel, and sets the result variable. channel <- 10 is syntax sugar for channel.Send(10). <-channel is an expression for channel.Receive(). Send and Receive operations are blocking ones: when sending a value to the channel, if it has no pending receive, the sending thread is blocked, and vice versa. This behavior gives some kind of coordination between the value producer of the channel and its value consumer.

You can use the channel many times:

channel = new Channel();
go for (k=1; k<=5; k++) channel.Send(k);
for (j=1; j<=5; j++)
  result = result + channel.Receive();

or in operator notation:

channel = new Channel();
go for (k=1; k<=5; k++) channel <- k;
for (j=1; j<=5; j++)
  result = result + <-channel;

Instead of generate only five values, you can write a goroutine feeding all numbers in a channel:

channel = new Channel();
running = true;
k = 0;
go while(running) channel <- k++;
for (value = <-channel; value<=10; value = <-channel)
  PrintLine(value);

The goruoutine don’t run forever: its run is controlled by the main thread, using channel blocking operation.

More interesting, you can use more channels to communicate different subprocesses:

channel = new Channel();
running = true;
k = 0;
go while(running) channel <- k++;
function filter(in, out)
{
  while (true) 
  {
    value = <-in;
    PrintLine("Received in filter " + value);
    if (value % 2)
      out <- value;
  }
}
odds = new Channel();
go filter(channel, odds);
for (number = <-odds; number <= 7; number = <-odds) 
  PrintLine("Received in main " + number);
  
running = false;

This code creates a channel, and a parallel thread that sends natural numbers to that channel. Another thread takes values from first channel, filter the odd values, and send them thru a second channel. The main thread takes values from this second channel, and prints the first results.

Then, we have all to create, connect and use, many channels. The next example (inspired in the Go language example at http://golang.org/doc/go_tutorial.html#tmp_346) prints the prime numbers less than 1000:

numbers = new Channel();
running = true;
k = 1;
go while(running) { k++; numbers <- k; }
function filter(in, out, prime)
{
  while (true) 
  {
    value = <-in;
    if (value % prime)
      out <- value;
  }
}
function makefilter(channel, number)
{
  newchannel = new Channel();
  go filter(channel, newchannel, number);
  return newchannel;
}
channel = numbers;
number = <-channel;
while (number < 1000) 
{
  PrintLine("Prime " + number);
  
  channel = makefilter(channel, number);
  
  number = <-channel;
}
running = false;

I’m planning to add a done command, to stop any child goroutine that is blocked. But now, I don’t need such feature yet. I should study the Go language capabilities: apparently, goroutines runs in only one thread, but I don’t sure. To read:

http://scienceblogs.com/goodmath/2009/11/the_go_i_forgot_concurrency_an.php

Subtle issue: in the above command, I wrote a makefilter function. In my first attempt, I wrote that code inline, but I had a problem: the go routine has access to extern variables in his lexical scope, and then, when the go routine code access, for example, the value of variable “channel”, that value could have been changed by the outer routine. The solution: write a makefilter function (a lambda with name) so it receives and keeps the original channel and related values for the goroutine, without been affected by the main routine. In the Go example, the author write the channel manipulation inline, so I should study the details of that implementation.

You can download current AjSharp code from http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/AjLanguage. The presented examples are in AjSharp.Tests/Examples and AjSharp.Console/Examples (AjSharp.Console is a console app to run AjSharp programs from files, or interactive ones).

Next steps on channels and goroutines: implement and use them directly in C#, in an spike, and then, add them to AjAgents or similar project.

Oh! I love the “cool view” of prime example at pastie http://pastie.org/758175 😉

Keep tuned!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

8 thoughts on “Channels and GoRoutines in AjSharp (Part 2)

  1. Pingback: GoRoutines and Channels in C# « Angel “Java” Lopez on Blog

  2. Pingback: AjSharp: Implementing Futures « Angel “Java” Lopez on Blog

  3. Pingback: Queue Channels in AjSharp « Angel “Java” Lopez on Blog

  4. Pingback: AjSharp: Implementando Futures - Angel "Java" Lopez

  5. Pingback: Queue Channels en AjSharp - Angel "Java" Lopez

  6. Pingback: Scripting WatiN using AjSharp « Angel “Java” Lopez on Blog

  7. Pingback: Memory transactions in AjSharp using References « Angel “Java” Lopez on Blog

  8. Pingback: Transacciones en memoria en AjSharp usando References - Angel "Java" Lopez

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s