2015-05-01 2 views
2

Как я могу запустить эти задачи одновременно, чтобы сообщения «Hello World from N» были замешаны?Задачи не запускаются одновременно

Мой вывод всегда выглядит так, за исключением того, что 1, 2 или 3 могут быть взаимозаменяемы.

Hello World from 1!
Hello World from 2!
Hello World from 3!

Это не похоже, что задачи выполняются одновременно. Похоже, что он работает в цепочке по принципу «первым пришел, первым обслужен».

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; 
+1

Можете ли вы привести пример подобного вывода вы ожидаете, например, вы ожидаете «HHeHlloel WorWorld» или подобное? Если это так, причина, по которой вы обычно не видите это, связана с буферизацией строк в операционной системе или библиотеке времени исполнения Ada. –

+0

@JackWhitham Хорошо, вот что я и думал. Но я не был уверен. Итак, задачи действительно работают одновременно в моем примере? – user1091344

+0

Да. Если вам нравится, вы можете проверить это, добавив цикл и задержку для каждой процедуры. –

ответ

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, попробуйте его с этой задержкой, так как это может привести к тому, что программа ищет другую готовую задачу с тем же приоритетом, который будет выполняться. Я ничего не гарантирую.

3

В задачи выполняются одновременно. Они просто недостаточно, чтобы этот параллелизм был видимым. Добавьте больше работы к каждой задаче, например. многократно распечатывая строку текста, и вы увидите ее.

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! 
Смежные вопросы