From: cmarquis@blackslacks.nswc.navy.mil (Cheryl Marquis)
Subject: Re: Activating tasks at Global Scope
Date: Mon, 15 Mar 1993 14:58:33 GMT
Date: 1993-03-15T14:58:33+00:00 [thread overview]
Message-ID: <1993Mar15.145833.18469@relay.nswc.navy.mil> (raw)
>The code below implements a producer-consumer system containing one
>producing task, two consuming tasks, and a bounded buffer task. I am only
>interested in the tasking interactions, so I've omitted the actual buffer
>manipulations. This code works fine under the Ada/ED compiler. However, I
>would prefer to put the tasks at global scope rather than nest them inside
>the producer_consumer procedure. I tried to do this by putting each task
>inside a package, but then I couldn't figure out how to activate the tasks
>when producer_consumer was invoked. What I'd like is an architecture where
>the tasks are automatically started before or at the same time the the main
>subprogram is invoked.
>If I've done anything particularly gross, feel free to comment
>appropriately. Nobody here knows Ada, so I put this together by copying
>fairly liberally from Ben-Ari's book, "Principles of Concurrent and
>Distributed Programming."
>Thanks,
>Scott
Scott as I see it you have two package options that will allow you a more
elegant start up without using delays.
They look basically alike the only difference is where the starting up of
the task is done. Below is some code that I hope will help you.
with Text_IO;
use Text_IO;
package My_Task_Stuff is
task Buffer is
--**** This entry provides a means of controlled task
-- start ups. Look at body to see how this works
entry Start_Up;
--****
entry insert(item: in Integer);
entry remove(item: out Integer);
--**** This entry provides a means of controlled task
-- shut downs. Look at body to see how this works
entry Shut_Down;
--****
end Buffer;
task Producer is
--**** This entry provides a means of controlled task
-- start ups. Look at body to see how this works
entry Start_Up;
--****
--**** This entry provides a means of controlled task
-- shut downs. Look at body to see how this works
entry Shut_Down;
--****
task Consumer1;
--**** This entry provides a means of controlled task
-- start ups. Look at body to see how this works
entry Start_Up;
--****
--**** This entry provides a means of controlled task
-- shut downs. Look at body to see how this works
entry Shut_Down;
--****
task Consumer2;
--**** This entry provides a means of controlled task
-- start ups. Look at body to see how this works
entry Start_Up;
--****
--**** This entry provides a means of controlled task
-- shut downs. Look at body to see how this works
entry Shut_Down;
--****
end My_Task_Stuff;
package body My_Task_Stuff is
task body Buffer is
count: Integer := 0;
begin
--**** put Start up before loop. Task will have to
-- wait here until the start up is called.
accept Start_Up;
-- any initializing can be done here also
loop
select when count < 10 =>
accept insert(item: in Integer) do
-- insert item into the buffer
null;
end insert;
count := count + 1;
or when count > 0 =>
accept remove(item: out Integer) do
-- remove an object from the buffer and assign it to item
null;
end remove;
count := count - 1;
or
--**** This will give you controlled task exits. You decide
-- when the task should end
accept Shut_Down;
exit;
end select;
end loop;
end Buffer;
task body Producer is
n: integer;
begin
--**** put Start up before loop. Task will have to
-- wait here until the start up is called.
accept Start_Up;
-- any initializing can be done here also
loop
--**** This will give you controlled task exits. You decide
-- when the task should end
select
accept Shut_Down;
exit;
else
-- give n an appropriate value
Buffer.insert(n);
end select;
end loop;
end Producer;
task body Consumer1 is
n: integer;
begin
--**** put Start up before loop. Task will have to
-- wait here until the start up is called.
accept Start_Up;
-- any initializing can be done here also
loop
--**** This will give you controlled task exits. You decide
-- when the task should end.
select
accept Shut_Down;
exit;
else
Buffer.remove(n);
-- do something with n
end select;
end loop;
end Consumer1;
task body Consumer2 is
n: integer;
begin
--**** put Start up before loop. Task will have to
-- wait here until the start up is called.
accept Start_Up;
-- any initializing can be done here also
loop
--**** This will give you controlled task exits. You decide
-- when the task should end
select
accept Shut_Down;
exit;
else
Buffer.remove(n);
-- do something with n
end select;
end loop;
end Consumer2;
--**** Now here you have a choice. You can either start these tasks
-- in the elaboration area of this package...
begin -- My_Task_Stuff
Producer.Start_Up;
Consumer1.Start_Up;
Consumer2.Start_Up;
end My_Task_Stuff;
with My_Task_Stuff;
procedure producer_consumer is
begin
null; -- will not terminate until all dependent
-- tasks terminate
end producer_consumer;
--**** ... or call the Start_Ups from the main procedure
end My_Task_Stuff
with My_Task_Stuff;
procedure producer_consumer is
begin
Producer.Start_Up;
Consumer1.Start_Up;
Consumer2.Start_Up;
end producer_consumer;
--**** One last thing; you can have procedure calls to your tasks
-- and hide the task inside the body instead of having a direct
-- task call specified in the Package Spec.
I hope I have helped and not confused you too badly. If you have
any questions feel free to email me.
Cheryl R.S. Marquis
cmarquis@unode1.nswc.navy.mil
<no clever quote to put here...............YET!>
next reply other threads:[~1993-03-15 14:58 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
1993-03-15 14:58 Cheryl Marquis [this message]
-- strict thread matches above, loose matches on Subject: below --
1993-03-10 3:32 Activating tasks at global scope Scott Meyers
1993-03-10 17:11 ` Robert I. Eachus
1993-03-11 3:56 ` Scott Meyers
1993-03-11 17:57 ` Dave Collard x7468
1993-03-11 2:51 ` Michael Feldman
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox