任务不会同时运行

时间:2015-05-01 10:24:31

标签: concurrency ada

如何让这些任务同时运行,以便来自N"" Hello World from N"消息会混淆吗?

除了可以互换1,2或3之外,我的输出看起来总是如此。

  

Hello World from 1!
  来自2的Hello World!
  来自3的Hello World!

它看起来不像任务同时运行。看起来它以先到先得的方式在链中运行。

main.adb

with Ada.Text_IO;

procedure Main is
   type Runnable_Type is access procedure;

   task type Filter (Runnable_Access : Runnable_Type) is
      entry start;
   end Filter;

   task body Filter is
   begin
      accept start;
      Runnable_Access.all;
   end Filter;

   procedure Run_1 is
   begin
      Ada.Text_IO.Put_Line ("Hello World from 1!");
   end Run_1;

   procedure Run_2 is
   begin
      Ada.Text_IO.Put_Line ("Hello World from 2!");
   end Run_2;

   procedure Run_3 is
   begin
      Ada.Text_IO.Put_Line ("Hello World from 3!");
   end Run_3;

   Filter_1 : Filter (Run_1'Access);
   Filter_2 : Filter (Run_2'Access);
   Filter_3 : Filter (Run_3'Access);
begin
   Filter_1.start;
   Filter_2.start;
   Filter_3.start;
end Main;

3 个答案:

答案 0 :(得分:3)

任务同时运行。他们只是没有做足以让这种并发性可见。为每项任务添加更多工作,例如反复打印出一行文字,你会看到它。

答案 1 :(得分:3)

使用Text_IO.Put_Line很可能会导致整行在一个操作中被写入,尽管可能是两个操作(一个输出字符串中的字符,一个输出到输出)是合理的新线)。但操作系统调用输出字符串(可能没有换行符)可能是一次调用,操作系统操作可能是不可中断的,或者它可能过快以至于很难用线程切换来中断。无论如何,这可能不会一次输出一个字符。 (我假设您在Linux或Windows系统或类似系统上运行,而不是运行时间最短的嵌入式系统等。)

您可以自己一次输出一个字符:

procedure Output_String (S : String) is
begin
    for I in S'range loop
        Text_IO.Put (S (I));
        --delay 0.0;
    end loop;
    Text_IO.New_Line;
end Output_String;

然后让您的Run程序调用此代码而不是Text_IO.Put_Line。如果它在没有delay 0.0的情况下不起作用,请尝试使用此延迟,因为这可能会导致程序查找其他具有相同优先级的就绪任务。但是,我不保证任何事情。

答案 2 :(得分:1)

正如杰克所说,它们同时运行。在Run_ *过程的不同部分放置一个忙循环显示了这一点。

with Ada.Text_IO;

procedure Main is
   type Runnable_Type is access procedure;

   task type Filter (Runnable_Access : Runnable_Type) is
      entry start;
   end Filter;

   task body Filter is
   begin
      accept start;
      Runnable_Access.all;
   end Filter;

   procedure Run_1 is
      counter : integer := 0;
   begin
      for i in 1..1000000 loop
         counter := counter + 1;
      end loop;
      Ada.Text_IO.Put_Line ("Hello World from 1a!");
      Ada.Text_IO.Put_Line ("Hello World from 1b!");
      Ada.Text_IO.Put_Line ("Hello World from 1c!");
   end Run_1;

   procedure Run_2 is
      counter : integer := 0;
   begin
      Ada.Text_IO.Put_Line ("Hello World from 2a!");
      for i in 1..1000000 loop
         counter := counter + 1;
      end loop;
      Ada.Text_IO.Put_Line ("Hello World from 2b!");
      Ada.Text_IO.Put_Line ("Hello World from 2c!");
   end Run_2;

   procedure Run_3 is
      counter : integer := 0;
   begin
      Ada.Text_IO.Put_Line ("Hello World from 3a!");
      Ada.Text_IO.Put_Line ("Hello World from 3b!");
      for i in 1..1000000 loop
         counter := counter + 1;
      end loop;
      Ada.Text_IO.Put_Line ("Hello World from 3c!");
   end Run_3;

   Filter_1 : Filter (Run_1'Access);
   Filter_2 : Filter (Run_2'Access);
   Filter_3 : Filter (Run_3'Access);
begin
   Filter_1.start;
   Filter_2.start;
   Filter_3.start;
end Main;

输出是:

Hello World from 2a!
Hello World from 3a!
Hello World from 3b!
Hello World from 2b!
Hello World from 2c!
Hello World from 1a!
Hello World from 1b!
Hello World from 1c!
Hello World from 3c!
相关问题