2015-05-01 155 views
2

如何讓這些任務同時運行,以便「N世界的Hello World」消息會混淆?任務不同時運行

我的輸出看起來總是像這樣,除了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

你能不能給排序輸出你期望,如示例你在期待「HHeHelel 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!