comp.lang.ada
 help / color / mirror / Atom feed
From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: Re: Structure of the multitasking server
Date: Fri, 19 Sep 2008 19:02:24 +0200
Date: 2008-09-19T19:02:26+02:00	[thread overview]
Message-ID: <1w9y1ocmu2cm3$.724p6fohqdvy$.dlg@40tude.net> (raw)
In-Reply-To: ho90bg.gnt.ln@hunter.axlog.fr

On Fri, 19 Sep 2008 15:34:00 +0200, Jean-Pierre Rosen wrote:

> Maciej Sobczak a �crit :
>> 
>> Imagine a server with fixed number of worker tasks. There is no queue
>> of jobs and jobs are immediately passed to one of the tasks that is
>> currently idle. There is a separate task (or just the main one) that
>> provides jobs for worker tasks.
> [...]
> 
> Why not simply use a rendezvous?
> Each worker has an entry Get_Job:
> 
>      task body Worker_Task is
>         Job : Job_Type;
>      begin
>         loop
>            Get_Job (Job);

You mean:

accept Get_Job (Requested : Job_Type) do
   Job := Requested;
end Get_Job;

>         end loop;
>      end Worker_Task;
> 
> and the server is simply (assuming Servers is an array of Worker_Task):
> 
>      loop
>         Job := ...
> 
>         Found_Worker := False;
>         for I in Servers'Range loop
>            select
>               Server (I).Get_Job (Job);
>               Found_Worker := True;
>               exit;
>            else
>               -- This server is busy
>               null;
>            end select;
>         end loop;
> 
>         if not Found_Worker then
>            --  all pipelines are busy,
>            --  but the overflow handling is not shown...
>         end if;
>      end loop;

This scheme requires some additional efforts in order to maintain the list
of idle workers.

I would use an inverse one, which is much simpler:

with Ada.Text_IO;  use Ada.Text_IO;

   type Job_Type is (Quit, Run);
   type Job (Kind : Job_Type := Quit) is null record;
   task type Worker;
   task Server is
      entry Get (Work : out Job);
   end Server;

   task body Server is
      Request : Job;
      Workers : array (1..5) of Worker;
   begin
      loop
            -- Get a job to do
         Request := (Kind => Run);
            -- Wait for a worker to come
         accept Get (Work : out Job) do
            Work := Request;
         end Get;
      end loop;

      -- Terminating workers
      for Index in Workers'Range loop
         Request := (Kind => Quit);
         accept Get (Work : out Job) do
            Work := Request;
         end Get;
      end loop;
   end Server;

   task body Worker is
      Work : Job;
   begin
      loop
         Server.Get (Work);
         case Work.Kind is
            when Quit => exit;
            when Run  => Put_Line ("Doing things");
         end case;
      end loop;
      Put_Line ("I am done");
   end Worker;

Note that task termination is usually a difficult problem in Ada. You
should pay an attention to this early. (The "terminate" alternative is
unusable in 80% cases.) In the solution above a special job type is used to
kill the worker.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



  reply	other threads:[~2008-09-19 17:02 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-09-19 12:21 Structure of the multitasking server Maciej Sobczak
2008-09-19 13:34 ` Jean-Pierre Rosen
2008-09-19 17:02   ` Dmitry A. Kazakov [this message]
2008-09-21 17:30     ` Maciej Sobczak
2008-09-21 19:24       ` Dmitry A. Kazakov
2008-09-21 21:27         ` Maciej Sobczak
2008-09-22  8:12           ` Dmitry A. Kazakov
2008-09-22 12:47             ` Maciej Sobczak
2008-09-22 14:11               ` Dmitry A. Kazakov
2008-09-23  8:07                 ` Maciej Sobczak
2008-09-23  9:37                   ` Dmitry A. Kazakov
2008-09-23 10:47                   ` Jean-Pierre Rosen
2008-09-21 17:23   ` Maciej Sobczak
2008-09-22  8:23     ` Jean-Pierre Rosen
2015-03-12 16:07   ` gautier_niouzes
2015-03-12 21:38     ` Jacob Sparre Andersen
2015-03-12 22:39       ` gautier_niouzes
2015-03-13  8:15         ` Dmitry A. Kazakov
2015-03-13 20:16           ` gautier_niouzes
2015-03-13 20:47             ` Dmitry A. Kazakov
2015-03-15  7:43               ` gautier_niouzes
2015-03-15  8:35                 ` Simon Wright
2015-03-15  8:52                 ` J-P. Rosen
2015-03-15  9:21                   ` Jacob Sparre Andersen
2015-03-15 16:04                     ` Brad Moore
2015-03-13 23:04             ` Randy Brukardt
2015-03-14  8:22               ` Simon Wright
2008-09-19 23:01 ` anon
2008-09-21 17:37   ` Maciej Sobczak
2008-09-22  2:32     ` anon
2008-09-22 13:05       ` Maciej Sobczak
2008-09-23  9:25         ` anon
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox