2014-11-02 49 views
-1

我需要给出我的任务正在使用的资源的名称,当我执行它时,因为一个资源始终在使用中,并且我使用SemaUse.K来传递信号量的私有计数值,因为他位于ArrLCO(0)中,所以资源总是被命名为“Dickdastardly”。经过数小时和数天的研究,我还没有能够正确地说出我的搜索结果,或找到对我特殊困境的有用答案。ADA:需要为我的资源分配名称,这些资源是由我的信号量管理的

--Tasktypes.adb 
WITH Ada.Text_IO, Ada.Calendar, Ada.Numerics.Float_Random; 
USE Ada.Text_IO, Ada.Calendar, Ada.Numerics.Float_Random; 

Procedure Tasktypes IS 
    --definitions 
    TYPE RequestType IS (Permission_To_Land, Call_The_Ball, Touch_Down); 
    TYPE ShuttleNameType IS (Atlantis, Challenger, Ranger, MeanMachine, HoganHero, Penelope, Jetson, Bullwinkle, PinkPanther, SecretSquirel); 
    TYPE LandingControlOfficerName IS (DickDastardly, Muttley, SlagBrothers); --Will I find a way to use these? 


    PACKAGE Duration_IO IS NEW Ada.Text_IO.Fixed_IO(Duration); USE Duration_IO; 
    PACKAGE IntIO IS NEW Ada.Text_IO.Integer_IO(Integer); USE IntIO; 
    PACKAGE ShuttleNameIO IS NEW ADA.Text_IO.Enumeration_IO(ShuttleNameType); USE ShuttleNameIO; 
    PACKAGE LandingControlOfficerNameIO IS NEW ADA.Text_IO.Enumeration_IO(LandingControlOfficerName); USE LandingControlOfficerNameIO; 

    --For part C we need 2 landing officers, aka available resources, so we initialize start_count to 2 
    PROTECTED TYPE Sema(Start_Count: Integer) IS 
     ENTRY Wait; --Queue is implied, task serialization like rendezvous 
     PROCEDURE Signal; --Re-entrant code, no queue no serialization 
     function K return Integer; 
     PRIVATE 
     Count: Integer := Start_Count; 
    END Sema; 


    PROTECTED BODY Sema IS 
     ENTRY Wait WHEN Count > 0 IS 
     BEGIN 
     Count := Count - 1; 
     END; 

     PROCEDURE Signal IS 
     BEGIN 
     Count := Count + 1; 
     END Signal; 

    function K return Integer is 
    begin return Count; end K; 
    END Sema; 



     RandNum: Generator; --notes on this in lab1 


     NameLCO: LandingControlOfficerName; 
     NumShuttles: Integer; 
     NameShuttles: ShuttleNameType; 
     NumLCOS: Integer := 2; 
     SemaUse: Sema(NumLCOS); 


    TASK TYPE LandingControlOfficer(LCOName: LandingControlOfficerName) IS 
     ENTRY Request (InRequestGiven: IN RequestType; InShuttleName: IN ShuttleNameType); 
    END LandingControlOfficer; 
    Type LCOAccess is Access LandingControlOfficer; 


    TYPE LCO_Array IS ARRAY(Integer RANGE <>) OF LCOAccess; 
    TASK TYPE Shuttle(ShuttleName: ShuttleNameType); 
    TYPE ShuttleAccess IS ACCESS Shuttle; 


     TYPE Shuttle_Array IS ARRAY(Integer RANGE <>) OF ShuttleAccess; 


     ArrLCO: LCO_Array(0..NumLCOS-1); 

    --critical resource where access must be controlled 
    TASK BODY LandingControlOfficer IS --Burris wants them both to be task types, unlike lab1. 
     --Local Variables 
     LCO: LandingControlOfficerName := LCOName; 
     RequestGiven: RequestType; 
     ShuttleName: ShuttleNameType; 


    BEGIN 
     LOOP 

     ACCEPT Request (inRequestGiven: IN RequestType; inShuttleName: IN ShuttleNameType) DO 
     RequestGiven := inRequestGiven; 
     ShuttleName := inShuttleName; 
     END Request; 

     CASE RequestGiven IS 
     WHEN Permission_To_Land => 
      DELAY Duration(Random(RandNum) * 10.0); 
      --Make Decision 
      Put(ShuttleName); PUT(" is Granted Permission To Land by: "); Put(LCO); new_line; 
     WHEN Call_The_Ball => 
      DELAY Duration(Random(RandNum) * 15.0); 
      --Prepare guidance system 
      Put(ShuttleName); Put(" call the ball! "); Put(LCO); New_Line; 
     WHEN Touch_Down => 
      Put(ShuttleName); Put(", permission is granted for final approach by: "); Put(LCO); New_Line; 
      DELAY Duration(Random(RandNum) * 25.0); 
      --Wait for Shuttle to land 
     END CASE; 
     END LOOP; 

    END LandingControlOfficer; 



--Task Type body for the Shuttle 
    TASK BODY Shuttle IS 
     Shuttle: ShuttleNameType := ShuttleName; 
     InitiateLandingSequence: Duration; 
     LandingComplete: Duration; 
    BEGIN 
     DECLARE 
     Hold: Integer; 
     BEGIN 

     FOR I IN 1..5 LOOP 

      begin 
      DELAY Duration(Random(RandNum) * 25.0); --Crew boarding and perform mission 

      SemaUse.Wait; 
      Put(Shuttle); Put(" entering its critical landing section."); New_Line(2); 
      InitiateLandingSequence := Seconds(Clock); 


       BEGIN 

        Hold := SemaUse.K; 
        ArrLCO(Hold).Request(Permission_To_Land, Shuttle); 
        ArrLCO(Hold).Request(Call_The_Ball, Shuttle); 
        DELAY Duration(Random(RandNum) * 2.0); --line up shuttle with mother ship 
        ArrLCO(Hold).Request(Touch_Down, Shuttle); 




       end; 



     LandingComplete := Seconds(Clock); 
     Put(Shuttle); Put(" docked in "); Put(LandingComplete - InitiateLandingSequence);Put(" seconds."); New_Line; 
     Put(Shuttle); Put(" leaving its critical section. Obtain new crew and start mission."); New_Line(2); 
        end; 
      SemaUse.Signal;--NEVER PUT ANYTHING BENEATH THIS> EVER 
     END LOOP; 
     end; 
    END Shuttle; 


    BEGIN 
    Put("Shuttle operations are authorized.");New_Line; 
    --Used as a container by the mother ship to launch and recover shuttles. 
    Put("Enter the number of Shuttles you would like: ");New_Line; 
    Get(NumShuttles); 

    Put("Enter the number of Landing Control Officers: ");New_Line; 
    Get(NumLCOS); 

    --DivideShuttles := NumShuttles/NumLCOS; --if 10/2, gives 5. If 10/3 gives 3 
    -- TempArraySize := NumShuttles; 
    --Brainstorming. Can do in psuedo parallel. can use divide shuttles to do for statement. 
    --For i in 0 .. NumLCOS-1 loop 
    -- TempArraySize := DivideShuttles; --I could end here if only using 2 LCOS 

     -- End Loop; 


    DECLARE 
    ArrShut: Shuttle_Array(0..NumShuttles-1); 


     BEGIN 
     FOR I IN 0..NumShuttles-1 LOOP 


      Put("Enter the names of the Shuttles: ");New_Line; 
      Get(NameShuttles); 
      ArrShut(I) := new Shuttle(NameShuttles); 

     END LOOP; 

     FOR I IN 0..NumLCOS-1 LOOP 
      Put("Enter the names of the Landing Control Officers: ");New_Line; 
      Get(NameLCO); 
      ArrLCO(I) := NEW LandingControlOfficer(NameLCO); --Arr 0 and Arr 1 hold the names. 
     END LOOP; 

END; 

END Tasktypes; 

我重定向输入文件,LabC.txt由以下部分组成:

10 
2 
Atlantis 
Challenger 
Ranger 
MeanMachine 
HoganHero 
Penelope 
Jetson 
Bullwinkle 
PinkPanther 
SecretSquirel 
DickDastardly 
Muttley 

我的输出的一个示例是:

Shuttle operations are authorized. 
Enter the number of Shuttles you would like: 
Enter the number of Landing Control Officers: 
Enter the names of the Shuttles: 
Enter the names of the Shuttles: 
Enter the names of the Shuttles: 
Enter the names of the Shuttles: 
Enter the names of the Shuttles: 
Enter the names of the Shuttles: 
Enter the names of the Shuttles: 
Enter the names of the Shuttles: 
Enter the names of the Shuttles: 
Enter the names of the Shuttles: 
Enter the names of the Landing Control Officers: 
Enter the names of the Landing Control Officers: 
CHALLENGER entering its critical landing section. 

MEANMACHINE entering its critical landing section. 

MEANMACHINE is Granted Permission To Land by: DICKDASTARDLY 
CHALLENGER is Granted Permission To Land by: MUTTLEY 
MEANMACHINE call the ball! DICKDASTARDLY 
MEANMACHINE docked in   10.860064438 seconds. 
MEANMACHINE leaving its critical section. Obtain new crew and start mission. 

BULLWINKLE entering its critical landing section. 

MEANMACHINE, permission is granted for final approach by: DICKDASTARDLY 
CHALLENGER call the ball! MUTTLEY 
CHALLENGER, permission is granted for final approach by: MUTTLEY 
CHALLENGER docked in   17.099900040 seconds. 
CHALLENGER leaving its critical section. Obtain new crew and start mission. 

PENELOPE entering its critical landing section. 

BULLWINKLE is Granted Permission To Land by: DICKDASTARDLY 
PENELOPE is Granted Permission To Land by: DICKDASTARDLY 
BULLWINKLE call the ball! DICKDASTARDLY 
PENELOPE call the ball! DICKDASTARDLY 
BULLWINKLE, permission is granted for final approach by: DICKDASTARDLY 
BULLWINKLE docked in   50.230774983 seconds. 
BULLWINKLE leaving its critical section. Obtain new crew and start mission. 

PINKPANTHER entering its critical landing section. 

在输出问题:佩内洛普应该使用一个名为“Muttley”而不是“Dickdastardly”的资源应该被信号量阻止。我很确定我有一个问题,我正在初始化/传递资源的名称的方式AKA“LandingControlOfficer”

我非常感谢任何创意或答案,因为我尝试了一些疯狂的方法到这一点。另外,如果不清楚,请随时要求我重新指定。

+0

我不能说出你认为的“资源”,我不能说真的,你的问题是什么。你的代码不完整,所以我不能运行它。你会想要发生什么?什么_does_发生?我不认为你的问题实际上是为你的资源考虑名字? – 2014-11-03 07:34:38

+0

您的问题尚不清楚,您的示例源文本不够完整,无法显示您的问题。 - 请解决这两个问题。 – 2014-11-03 08:32:20

+0

我已经添加了所有的代码,并且可以在ada中进行编译。我也尽可能清楚地重述了这个问题,包括输入,输出和对输出结果的解释。 – user4208606 2014-11-03 15:12:48

回答

0

我不确定有多少个坞站(跑道?)。这可能是因为有着陆控制人员的坞站数量很多,或者有数量有限(大于或少于LCO的当前数量)。我猜想前者,因为在您的管理扩展坞的描述中没有任何内容。

在任何一种情况下,似乎每个航天飞机着陆序列都由特定的着陆控制人员监督,因此您的问题是在序列开始时将可用LCO池中的LCO分配给航天飞机,并且序列结束时将该LCO返回到池中;而关键资源不是单个的LCO,而是可用的LCO池。

如何确定其中 LCO?很难通过计算当前可用LCO的数量,这是您当前的代码所做的。没有理由让LCOs按照他们分配的相同顺序获得免费(除非一次只有一个对接站并且只有一个着陆序列);一些着陆将比其他着陆短。

摆脱你的信号量Start_Count;其Count应该初始化为1.摆脱K

如果需要,你可以告诉LCO是在LCO_Array哪个条目,当您创建它,通过第二判别:

task type LandingControlOfficer 
    (LCOName : LandingControlOfficerName; 
    Index : Integer) is 

...但我不认为你这样做。

保持每个LCO可用性指标:

type LCOAccess is access LandingControlOfficer; 
type LCO_Data is record 
    The_LCO : LCOAccess; 
    Available : Boolean := True; 
end record; 
type LCO_Array is array(Integer range <>) of LCO_Data; 

有化LCO的分配/释放方案:

procedure Grab_LCO (Grabbed : out LCOAccess) is 
begin 
    SemaUse.Wait; 
    for J in ArrLCO'Range loop 
     if ArrLCO (J).Available then 
     ArrLCO (J).Available := False; 
     Grabbed := ArrLCO (J).The_LCO; 
     SemaUse.Signal; 
     return; 
     end if; 
    end loop; 
    Grabbed := null; 
    SemaUse.Signal; 
end Grab_LCO; 

procedure Free_LCO (The_LCO : in out LCOAccess) is 
begin 
    if The_LCO = null then 
     raise Program_Error with "trying to free a null LCO"; 
    end if; 
    SemaUse.Wait; 
    for J in ArrLCO'Range loop 
     if The_LCO = ArrLCO (J).The_LCO then 
     if ArrLCO (J).Available then 
      raise Program_Error with "trying to free an already-free LCO"; 
     end if; 
     ArrLCO (J).Available := True; 
     The_LCO := null; 
     SemaUse.Signal; 
     return; 
     end if; 
    end loop; 
    raise Program_Error with "trying to free an unknown LCO"; 
    -- what happens to SemaUse, then? 
end Free_LCO; 

在任务体Shuttle,通过更换Hold

Allocated_LCO : LCOAccess; 

执行任务后,

更换

Hold := SemaUse.K; 

通过

loop 
    Grab_LCO (Grabbed => Allocated_LCO); 
    exit when Allocated_LCO /= null; 
    Put (Shuttle); Put (" didn't get an LCO yet"); New_Line; 
    delay 1.0; 
end loop; 

通过

Free_LCO (The_LCO => Allocated_LCO); 

通过Allocated_LCO更换ArrLCO(Hold)贯穿始终,并替换最后SemaUse.Signal作为临别认为:这是真的阿达很不合适使用像semaphor这样的低级构造当您拥有受保护的对象时,可以管理资源。创建Ada运行时系统的非常聪明的人(不是我!)使用底层构造(包括信号量)来实现PO来满足Ada语义,例如确保在离开条目/子程序时正确管理内部信号等,甚至由于例外;使用所有这些巧妙的脚手架来重建信号量及其所有问题是错误的。

+0

非常感谢。我意识到我的主要问题是我忽略了利用我的基本数据结构来维护LCO。 – user4208606 2014-11-25 19:18:15