代码 (Ada)4. TASK LIFE SPANS

练习一 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,其中的顺序执行就在于其中一组已经排列好了,而等待下一组的排列。所以我们做的就是让他们同时进行。

效果:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容

  • 很实用的编程英语词库,共收录一千五百余条词汇。 第一部分: application 应用程式 应用、应用程序app...
    春天的蜜蜂阅读 1,335评论 0 22
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,580评论 18 139
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy阅读 9,501评论 1 51
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,560评论 18 399
  • 第五十九天 今天去把一直想做的事儿做了,报了名以后就要好好坚持下去。 今天晚上要做的最要紧的事情是把这周的工作、生...
    云小5阅读 126评论 0 0