问题描述
已经给我下面的代码,并要求实现一个信号量。
with Ada.Text_IO; use Ada.Text_IO;
with Id_Dispenser;
with Semaphores; use Semaphores;
procedure Philos is
No_of_Philos : constant Positive := 5;
Meditation : constant Duration := 0.0;
type Table_Ix is mod No_of_Philos;
Forks : array (Table_Ix) of Binary_Semaphore (Initially_Available => True);
package Index_Dispenser is new Id_Dispenser (Element => Table_Ix);
use Index_Dispenser;
task type Philo;
task body Philo is
Philo_Nr : Table_Ix;
begin
Dispenser.Draw_Id (Id => Philo_Nr);
Put_Line (“Philosopher” & Table_Ix’Image (Philo_Nr) & “ looks for forks.”);
Forks (Philo_Nr).Wait; delay Meditation; Forks (Philo_Nr + 1).Wait;
Put_Line (“Philosopher” & Table_Ix’Image (Philo_Nr) & “ eats.”);
Forks (Philo_Nr).Signal; Forks (Philo_Nr + 1).Signal;
Put_Line (“Philosopher” & Table_Ix’Image (Philo_Nr) & “ dropped forks.”);
end Philo;
Table : array (Table_Ix) of Philo; pragma Unreferenced (Table);
begin
null;
end Philos;
该任务需要一个Semaphores
软件包和一个Id_Dispenser
软件包。我是Ada的新手,但是软件包的含义是什么?这是指规范和正文,还是只是一个,那么我应该如何实现呢?
解决方法
包装是什么意思?
根据建议here,Ada 软件包为modular programming提供了支持封装的功能。
该任务需要一个
Semaphores
软件包。
为此,Ada提供了protected types“它封装了类型的对象的私有数据并提供了对其的同步访问,而没有引入其他任务。”可以在here中找到更多讨论和示例。
在dining philosophers problem的上下文中,完整的example值得一读;它包含在share/examples/gnat/simple_project
中的GNAT community edition中。特别是package Chop
导出protected type Stick
; Stick
的每个实例都有一个entry Pick_Up
和procedure Put_Down
。然后package Room
可以为用餐者提供一系列餐具,与您的片段中的Forks
相对应。
Sticks : array (Table_Type) of Chop.Stick;
,
关于“什么是包裹”,请查看Packages section in the Ada Wikibook。
所有软件包都包含规范部分。大多数还具有一个主体(如果规范允许一个主体,例如通过声明一个子程序,则实际上必须有一个主体)。
您可以在Wikibook section on Tasking中找到有关实现信号灯的讨论,其中包括Semaphore_Protected_Type
的代码。
您需要的是
package Semaphores is
protected type Binary_Semaphore (Initially_Available : Boolean) is
entry Wait;
procedure Signal;
private
Available : Boolean := Initially_Available;
end Binary_Semaphore;
...
end Semaphores;