Re: Running a background task
- From: "Jeffrey R. Carter" <spam.jrcarter.not@xxxxxxxxxxxx>
- Date: Fri, 16 May 2008 00:16:05 GMT
Bender wrote:
Hi, I'm pretty new to Ada, and need to figure out a way to kick off a
background task that runs more or less forever, while normal execution
of the program continues.
Thus far I've figured out how to create a task and start it, but the
procedure calling it requires the task to finish before continuing
on. I'm sure I just must be using the wrong mechanisms, but I can't
really figure out the answer.
Task definition
---------------------
(spec)
task type Poll_For_Status is
entry On_String (String : in SideAB)
1. You're missing the terminator semicolon.
2. It's generally not a good idea to reuse the identifier "String", since it hides the predefined type String, which will cause confusing error msgs if you ever try to use that type.
end Poll_For_Status;
type Task_Access is access Poll_For_Status;
Status_Task : Task_Access;
You have no need for the access type. You can simply say
Status_Task : Poll_For_Status;
Status_Task won't do anything, since it waits for a call to On_String.
You can simplify this even more by saying
task Status_Task is
entry On_String (...);
end Status_Task;
This assumes that Status_Task is the only instance of Poll_For_Status.
(body)
task body Poll_For_Status is
begin
accept On_String (String : in SideAB) do
loop
delay 3.0
Another missing terminator semicolon.
Send_Status_Req (String);
end loop;
This infinite loop is inside the accept for On_String, which means the task that calls On_String will be blocked indefinitely.
end On_String;
end Poll_For_Status;
Calling procedure
------------------------
procedure Handle_Msg(...) is
String : SideAB;
...
begin
...
Status_Task := new Poll_For_Status
As mentioned above, this is unneeded. And it's missing the terminator semicolon.
Status_Task.On_String (String);
...
If I remove the loop in the task body, it works fine. Putting it in
seems to halt execution.
Am I missing anything?
My comment on the loop inside the accept is what's confusing you. A rendezvous (when a task calls another task's entry) blocks the calling task until it completes. Since you have an infinite loop inside the accept, the rendezvous never completes and Handle_Msg never returns from the call to On_String.
Possible solutions include
1. Having the task store the value passed to it:
Side : Sideab;
begin -- Poll_For_Status;
accept On_String (String : in Sideab) do
Side := String;
end On_String;
loop
...
2. Communicating via a protected object rather than a rendezvous. This is a bigger change, but depending on your needs might result in a better design.
It may not be important to you, but your loop does not execute every 3 seconds. There may be some time after the delay expires before the task starts executing again, and using "delay" allows those times to accumulate; there's also the time to call the subprogram. If you want it to be as close to every 3 seconds as you can get, you should use the "delay until" statement.
--
Jeff Carter
"Many times we're given rhymes that are quite unsingable."
Monty Python and the Holy Grail
57
.
- Follow-Ups:
- Re: Running a background task
- From: Bender
- Re: Running a background task
- References:
- Running a background task
- From: Bender
- Running a background task
- Prev by Date: Re: Running a background task
- Next by Date: Re: Running a background task
- Previous by thread: Re: Running a background task
- Next by thread: Re: Running a background task
- Index(es):
Relevant Pages
|