提前感谢您的帮助。我目前正在做一些关于ada编程的初学者工作,我从http://libre.adacore.com/download/configurations#安装了GNAT Programming Studio(GPS) 我有Windows 10 64位。我在学校获得了以下代码:
pragma Task_Dispatching_Policy(FIFO_Within_Priorities);
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Real_Time; use Ada.Real_Time;
procedure PeriodicTasks is
Start : Time;
package Duration_IO is new Ada.Text_IO.Fixed_IO(Duration);
package Int_IO is new Ada.Text_IO.Integer_IO(Integer);
task type T(Id: Integer; Period : Integer) is
pragma Priority(Id);
end;
task body T is
Next : Time;
X : Integer;
begin
Next := Start;
loop
Next := Next + Milliseconds(Period);
-- Some dummy function
X := 0;
for Index in 1..5000000 loop
X := X + Index;
end loop;
Duration_IO.Put(To_Duration(Clock - Start), 3, 3);
Put(" : ");
Int_IO.Put(Id, 2);
Put_Line("");
delay until Next;
end loop;
end T;
-- Example Task
Task_P10 : T(10, 250);
Task_P12 : T(12, 500);
Task_P14 : T(14, 500);
Task_P16 : T(16, 250);
Task_P18 : T(18, 500);
Task_P20 : T(20, 250);
begin
Start := Clock;
null;
end PeriodicTasks;
我在GPS中打开文件,构建它(没有错误)并运行它但它没有显示任何打印输出。我听说有时你会遇到多核CPU的问题,所以每次打开gps.exe时,CPU亲和力都只设置为一个CPU,它总是"以管理员身份运行"。但是,这也没有用,我没有输出。 我决定使用Oracle Virtual Box并设置一个只有一个处理器的Ubuntu OS(32位)。安装了使用gnatmake编译的GNAT工具,使用./periodictasks运行,然后猜测该程序是做了它应该做的事情并打印出信息。
在这么长的故事之后,有人知道为什么会这样吗?它可能是64位与32位的情况吗?
非常感谢!
答案 0 :(得分:2)
直到最近,GNAT默认情况下都没有检查整数溢出。它确实检查了约束错误,例如将0分配给Positive
。
我们中的许多人认为这是编译器开发人员的一个奇怪的选择,因为它导致了许多问题,其根本原因是无法处理整数溢出。最近的变化让我们假设开发人员现在同意了!
由于声明
,您的问题就出现了for Index in 1..5000000 loop
X := X + Index;
end loop;
最终会得到X~10 ^ 13,它不适合32位整数(它适合64位整数,但如果不是,则大多数为Long_Long_Integer
所有GNAT平台)。
您的Windows编译器可能是GNAT GPL 2016,它显示了新的行为,而Ubuntu编译器是较旧的FSF GCC。
您可以使用编译器开关-gnato0
告诉Windows编译器使用旧行为。
您可以使用编译器开关-gnato
告诉您的Ubuntu编译器使用新行为。
要获取任务中未处理的异常(否则会无声地死亡)的异常消息,您可以添加
GNAT.Exception_Traces.Trace_On (GNAT.Exception_Traces.Unhandled_Raise);
在主程序的开头。
答案 1 :(得分:2)
在执行开始时,会打印垃圾,打印信息的唯一任务是
Task_P20
&Task_P18
。
如§9.2 Task Execution - Task Activation中所述,任务在PeriodicTasks
的第一个语句执行之前一起激活。虽然所有任务都在运行,但是,在初始化 Start
之前,部分或全部任务可能会尝试生成输出。至少要将Start
初始化为尽可能接近其声明,
Start : Time := Clock;
并将身体留空,
begin
null;
end PeriodicTasks;
此外,无法激活的任务将成为已完成的任务,不会产生任何输出。