Reputation: 882
Tasks in Ada 'accept start do ' statement is not completing its all execution ?
accept start do
Here 'do' keyword force compiler to finish all the execution mention between do and end keyword but why in below code its not happen ?why it is printing other task body i.e first(task name) not its own task(i.e start) in the below code? please help me to understand where i went wrong?
procedure main is
task first is
entry start;
end first;
task body first is
begin
accept start ; -- i am not using do here
put_line("first");
put_line("first");
put_line("first");
end first;
task second is
entry start;
end second;
task body second is
begin
accept start do -- here 'do' keyword will force compile to finish all the execution between keyword 'do' and end? but why it is mixing statement of task first?
for i in 1..10 loop
put_line("second");
end loop;
end start;
end second;
begin
first.start;
second.start;
end main;
output-
second
second
second
second
first -- why first get printed between before completing second?
first
first
second
second
second
second
second
second
Note-every time its give different o/p i was expecting if task second gets activated first then it should first complete all the statement between do and end it should not print other task statement till second gets finish then its should go for other task
Upvotes: 2
Views: 354
Reputation: 25501
After first.start
is accepted, first
is ready to output a line whenever it gets a processor, while main
carries on and calls second.start
.
After second.start
is accepted, second
outputs its 10 lines before returning control to main
.
But, what happens if deep within the Ada runtime system, or even the operating system, it turns out that put_line
involves blocking?
In that case, second
is blocked, so first
is free to carry on and output one of its lines. At which point first
is likely to be blocked again, so second
gets a chance ...
So it seems that your OS (and mine - Mac OS X) block, or at any rate can block, inside put_line
.
Overall, the fact is that standard output - which is what you are accessing via put
or put_line
- is a shared resource which you are accessing from two tasks. The Ada language (ARM 9(8)) says
tasks can communicate indirectly by reading and updating (unprotected) shared variables, presuming the access is properly synchronized through some other kind of task interaction.
and you are not doing any form of synchronization, so the system can do what it feels like; the results aren’t defined by the language. In similar circumstances I’ve seen one task outputting “hello” and another outputting “world” resulting in “hweolrllod”.
Upvotes: 5