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
next prev parent 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