Angel "Java" Lopez

NET, Java, PHP y Desarrollo de Software

This Blog

Syndication

Search

Tags

Community

Email Notifications

Archives

.NET

ASP.NET

Windows Form

VB.NET

C#

Sitios

Blogs

Queue Channels en AjSharp

Hace una semanas, implementé channels en mi intérprete AjSharp. Pueden leer sobre el tema en:

Channels and GoRoutines in AjSharp (part 1)
Channels and GoRoutines in AjSharp (part 2)

Canales y GoRoutines en AjSharp (Part 1)
Canales y GoRoutines en AjSharp (Part 2)

Si uno lee el valor de un canal, y no hay valor disponible, el thread que está tratando de leer se bloquea hasta que el valor esté disponible. Esta es una manera de sincronizar consumidores y productores que operan sobre el canal. Pero algunas veces queremos poner un valor en un canal y continua, sin bloqueo. Para eso, agregué una “queue channel” (podría llamarla queued channel): pueden poner N valores en el canal sin bloqueo, porque se van guardando en una cola interna. El tamaño de la cola se determina en un parámetro en el constructor. La cola está limitada en tamaño para poder preservar sus capacidades de sincronizació.

El nombre de la nueva clase es QueueChannel. Un test:

        [TestMethod]
        public void CreateAndUseQueueChannelWithTenElements()
        {
            QueueChannel channel = new QueueChannel(10);
            for (int k = 1; k <= 10; k++)
                channel.Send(k);
            for (int k = 1; k <= 10; k++)
                Assert.AreEqual(k, channel.Receive());
        }

El canal recibe 10 valores sin bloquearse. Si enviamos más valores, debemos usar otro thread:

        [TestMethod]
        public void CreateAndUseQueueChannelWithMoreEntriesThanSize()
        {
            QueueChannel channel = new QueueChannel(10);
            Thread thread = new Thread(new ThreadStart(delegate()
            {
                for (int k = 1; k <= 20; k++)
                    channel.Send(k);
            }));
            thread.Start();
            for (int k = 1; k <= 20; k++)
                Assert.AreEqual(k, channel.Receive());
        }

Para probarlo en un ejemplo, reescribí el ejemplo de números primos usando queue channels:

numbers = new QueueChannel(10);
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 QueueChannel(10);
  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;

El código está en mi Google code project:

http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/AjLanguage

Mi motivación para un queue channel apareció en ejemplo de algoritmo genético en paralelo, que sufría de demasiados bloqueos. Veo que un buen algoritmo no necesitaría colas, pero si uno tiene muchos consumidores y productores, y un thread produce valores para ser colocados en más de un canal, podría pasar que al colocar el valor en el canal A, no lleguemos a entregar el valor en el canal B, por bloqueo en la primera operación. Una forma de evitar el bloqueo es usando el comando go:

go channel <- newvalue;

Pero me parece que es demasiado lanzar una goroutine solamente para alimentar un canal.

Tendría que presentar el algoritmo genético en paralelo (que ya hace unos meses presenté), y escribir algunas ideas para implementar un actor model en AjSharp, y usar agentes distribuidos.

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Published Fri, Jan 29 2010 10:47 by lopez

Comments

# re: Queue Channels en AjSharp@ Friday, January 29, 2010 5:57 AM

Me alegra que nuestras conversaciones en Hogwarts lo inspiren, Maestro. :)

ajSharp for the win!

Martin Salias

Leave a Comment

(required) 
(required) 
(optional)
(required) 
If you can't read this number refresh your screen
Enter the numbers above: