美文网首页
代码 (Ada)4. TASK LIFE SPANS

代码 (Ada)4. TASK LIFE SPANS

作者: 何大炮 | 来源:发表于2017-08-22 18:45 被阅读0次

    练习一 Scope

    任何task都要在他的子任务结束后才能结束。
    对于以下的程序 请给出输出顺序

    with Ada.Calendar;      use Ada.Calendar;
    with Ada.Float_Text_IO; use Ada.Float_Text_IO;
    with Ada.Text_IO;       use Ada.Text_IO;
    
    procedure Task_Scopes is
    
       Start_Up_Time : constant Time := Clock;
    
       procedure Put_Line_Time (S : String) is
    
       begin
          -- Prefixes the time since startup as seconds with two decimal places
          Put (Float (Clock - Start_Up_Time), 1, 2, 0); Put_Line (" seconds: " & S);
       end Put_Line_Time;
    
       task type Outer_Type;
       type Outer_Type_Ptr is access Outer_Type;
       task body Outer_Type is
    
       begin
          delay 0.6; Put_Line_Time ("-- End of an outer task");
       end Outer_Type;
    
       task Static_Outer_Task;
       task body Static_Outer_Task is
    
       begin
          delay 0.1; Put_Line_Time ("Start of Static_Outer_Task");
          declare
    
             task type Inner_Type;
             type Inner_Type_Ptr is access Inner_Type;
             task body Inner_Type is
    
             begin
                delay 0.6; Put_Line_Time ("-- End of an inner task");
             end Inner_Type;
    
             task Static_Inner_Task;
             task body Static_Inner_Task is
    
             begin
                delay 0.2; Put_Line_Time ("Start of Static_Inner_Task");
                declare
                   Inner_Task_Instance : Inner_Type;
                   Outer_Task_Instance : Outer_Type;
                   Dynamic_Inner_Instance : Inner_Type_Ptr := new Inner_Type;
    --                 Dynamic_Outer_Instance : Outer_Type_Ptr := new Outer_Type;
                begin
                   delay 0.3; Put_Line_Time ("End of Static_Inner_Task declare block");
                end;
                delay 0.1; Put_Line_Time ("End of Static_Inner_Task");
             end Static_Inner_Task;
    
          begin
             delay 0.4; Put_Line_Time ("End of Static_Outer_Task declare block");
          end;
          delay 0.1; Put_Line_Time ("End of Static_Outer_Task");
       end Static_Outer_Task;
    
    begin
       delay 0.2; Put_Line_Time ("Start of main scope");
       delay 0.2; Put_Line_Time ("End of main scope");
    end Task_Scopes;
    
    

    运行结果:

    分析:Ada中有两个种类的task

    1. static
      这一类都是直接在声明然后使用。他的存活范围为生成task时所在的范围(scope)。
    2. dynamic
      这一类就使用access关键字来表示(指针):

    声明:

    type Outer_Type_Ptr is access Outer_Type;

    实例化:

    Dynamic_Outer_Instance : Outer_Type_Ptr := new Outer_Type;

    这一类的存活范围为其原task声明所在的范围,即与其在哪里被生成无关。
    之所以用到了指针而不用重新声明一个新的task,主要是考虑到了存储空间的问题。

    最后,散乱分布的相同的dynamic task会被同一个task 回收,这是最有利的一点。

    练习二 Concurrent Mergesort

    实现一个concurrent mergesort。

    with Ada.Exceptions; use Ada.Exceptions;
    with Ada.Text_IO;    use Ada.Text_IO;
    with CPU_Counter;    use CPU_Counter;
    
    procedure Concurrent_Mergesort (Sort_Field : in out Element_Array) is
    
       procedure Mergesort (F : in out Element_Array) is
    
       begin
          if F'Length > 1 then
             declare
                Middle : constant Index := Index'Val (Index'Pos (F'First) + F'Length / 2);
    
                subtype Low_Range  is Index range F'First .. Index'Pred (Middle);
                subtype High_Range is Index range Middle  .. F'Last;
    
                F_Low  : aliased Element_Array := F (Low_Range);
                F_High : aliased Element_Array := F (High_Range);
    
                Gained_Agent : Boolean := False;
                        
             begin
                if CPUs_Potentially_Available then
                   CPU_Count.Try_Check_One_Out (Gained_Agent);
                end if;
    
                if Gained_Agent then   ## 关键部分
                   declare
                      task sort_L;
                      
                      task body sort_L is 
                      begin                      
                         Mergesort (F_Low);
                      end;
                      
                      task  sort_H;           
                      
                      task body sort_H is 
                      begin
                         Mergesort (F_High);
                      end;
                      
                   begin
                      null;
                   end;                ##关键部分
                   
                else
                   Mergesort (F_Low);
                   Mergesort (F_High);
                end if;
    
                declare
                   Low          : Low_Range  := Low_Range'First;
                   High         : High_Range := High_Range'First;
                   Low_Element  : Element    := F_Low  (Low);
                   High_Element : Element    := F_High (High);
    
                begin
                   Merge : for i in F'Range loop
    
                      if Low_Element < High_Element then
                         F (i) := Low_Element;
                         if Low = F_Low'Last then
                            F (Index'Succ (i) .. F'Last) := F_High (High .. F_High'Last);
                            exit Merge;
                         else
                            Low  := Index'Succ (Low); Low_Element  := F_Low (Low);
                         end if;
                      else
                         F (i) := High_Element;
                         if High = F_High'Last then
                            F (Index'Succ (i) .. F'Last) := F_Low (Low .. F_Low'Last);
                            exit Merge;
                         else
                            High := Index'Succ (High); High_Element := F_High (High);
                         end if;
                      end if;
                   end loop Merge;
                end;
             end;
          end if;
       end Mergesort;
    
    begin
       Mergesort (Sort_Field);
    end Concurrent_Mergesort;
    

    在以上关键部分,我用了两个并行的task 代替了原来顺序执行的 Mergesort (F_Low), Mergesort (F_High);
    因为mergesort的关键就是separation,其中的顺序执行就在于其中一组已经排列好了,而等待下一组的排列。所以我们做的就是让他们同时进行。

    效果:

    相关文章

      网友评论

          本文标题:代码 (Ada)4. TASK LIFE SPANS

          本文链接:https://www.haomeiwen.com/subject/cdrldxtx.html