Channel Synchronization in Ada

with Ada.Text_IO;
with Ada.Calendar;

procedure Channel_Synchronization is
   package IO renames Ada.Text_IO;
   package Calendar renames Ada.Calendar;

   protected type Done_Channel is
      entry Wait;
      procedure Signal;
   private
      Done : Boolean := False;
   end Done_Channel;

   protected body Done_Channel is
      entry Wait when Done is
      begin
         null;
      end Wait;

      procedure Signal is
      begin
         Done := True;
      end Signal;
   end Done_Channel;

   task Worker is
      entry Start(Channel : in out Done_Channel);
   end Worker;

   task body Worker is
      Channel : access Done_Channel;
   begin
      accept Start(Channel : in out Done_Channel) do
         Worker.Channel := Channel'Access;
      end Start;

      IO.Put("working...");
      delay 1.0;
      IO.Put_Line("done");

      Channel.Signal;
   end Worker;

   Done : aliased Done_Channel;
begin
   Worker.Start(Done);
   Done.Wait;
end Channel_Synchronization;

This Ada program demonstrates channel synchronization, which is similar to the concept in the original example. Here’s an explanation of the code:

  1. We define a protected type Done_Channel that acts as our synchronization mechanism. It has an entry Wait and a procedure Signal, mimicking the behavior of a channel.

  2. The Worker task represents our worker “goroutine”. It takes a Done_Channel as a parameter when started.

  3. In the Worker task, we simulate work by printing “working…”, waiting for a second, and then printing “done”. After this, it signals completion using the Done_Channel.

  4. In the main procedure, we create a Done_Channel, start the Worker task, and then wait for it to complete using Done.Wait.

To run this program:

$ gnatmake channel_synchronization.adb
$ ./channel_synchronization
working...done

If you removed the Done.Wait; line from this program, the program would exit before the Worker even started, similar to the behavior described in the original example.

Ada’s tasking model provides a built-in synchronization mechanism, which we’ve used here to replicate the behavior of Go’s channels. While the syntax and specifics differ, the core concept of synchronizing concurrent operations remains the same.

查看推荐产品

Comments powered by Disqus