gpt4 book ai didi

concurrency - Ada 并发问题

转载 作者:行者123 更新时间:2023-12-04 18:37:33 25 4
gpt4 key购买 nike

我需要一些帮助和一些见解。这是 Ada-2005 中的一个程序,有 3 个任务。输出是“z”。如果这 3 个任务没有按照它们在程序中的放置顺序发生,则输出可能会从 z = 2、z = 1 到 z = 0 变化(这在程序中很容易看到,尝试互斥以确保输出是 z = 2)。

WITH Ada.Text_IO; USE Ada.Text_IO;
WITH Ada.Integer_Text_IO; USE Ada.Integer_Text_IO;
WITH System; USE System;

procedure xyz is
x : Integer := 0;
y : Integer := 0;
z : Integer := 0;

task task1 is
pragma Priority(System.Default_Priority + 3);
end task1;

task task2 is
pragma Priority(System.Default_Priority + 2);
end task2;

task task3 is
pragma Priority(System.Default_Priority + 1);
end task3;

task body task1 is
begin
x := x + 1;
end task1;

task body task2 is
begin
y := x + y;
end task2;

task body task3 is
begin
z := x + y + z;
end task3;

begin
Put(" z = ");
Put(z);
end xyz;

我第一次尝试这个程序

(a) 没有编译指示,结果:在 100 次尝试中,出现 2: 86,出现 1: 10,出现 0: 4。

然后

(b) 使用编译指示,结果:在 100 次尝试中,出现 2: 84,出现 1: 14,出现 0: 2。

这是出乎意料的,因为两个结果几乎相同。这意味着无论是否有编译指示,输出都具有相同的行为。

那些 Ada 并发专家请阐明这个主题。还邀请使用信号量的替代解决方案(如果可能)。

进一步我认为,对于关键过程(这就是我们对 Ada 所做的),使用编译指示时,结果应该是 z = 2,始终为 100%,因此或以其他方式,该程序应被称为 85% 关键! !!! (艾达不应该这样)

最佳答案

执行这三个操作的 protected 对象可能看起来像这样。但请注意,这只是确保三个变量 x、y 和 z 与更新发生的顺序一致;它没有提及订单。

   protected P is
procedure Update_X;
procedure Update_Y;
procedure Update_Z;
function Get_Z return Integer;
private
X : Integer := 0;
Y : Integer := 0;
Z : Integer := 0;
end P;
protected body P is
procedure Update_X is
begin
X := X + 1;
end Update_X;
procedure Update_Y is
begin
Y := Y + X;
end Update_Y;
procedure Update_Z is
begin
Z := X + Y + Z;
end Update_Z;
function Get_Z return Integer is
begin
return Z;
end Get_Z;
end P;

另一方面,为了确保三个任务以正确的顺序“提交结果”,您可以重写 P,以便对 Update_Y 的调用将阻塞,直到调用 Update_X:Get_Z 现在必须是带有输出参数而不是函数的条目。

  protected P is
entry Update_X;
entry Update_Y;
entry Update_Z;
entry Get_Z (Result : out Integer);
private
X_Updated : Boolean := False;
Y_Updated : Boolean := False;
Z_Updated : Boolean := False;
X : Integer := 0;
Y : Integer := 0;
Z : Integer := 0;
end P;
protected body P is
entry Update_X when True is
begin
X := X + 1;
X_Updated := True;
end Update_X;
entry Update_Y when X_Updated is
begin
Y := Y + X;
Y_Updated := True;
end Update_Y;
entry Update_Z when Y_Updated is
begin
Z := X + Y + Z;
Z_Updated := True;
end Update_Z;
entry Get_Z (Result : out Integer) when Z_Updated is
begin
Result := Z;
end Get_Z;
end P;

这三个任务现在可以具有您喜欢的任何优先级。但调用 Update_Z 的任务将阻塞,直到其他两个任务报告为止。

关于concurrency - Ada 并发问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2493841/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com