Channels in Ada

Channels in Ada

Channels are the pipes that connect concurrent tasks in Ada. You can send values into channels from one task and receive those values into another task.

Create the Channel

Create a new channel. Channels in Ada can be implemented using a protected object that encapsulates a queue for inter-task communication.

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Synchronous_Task_Control;
with Ada.Containers.Financial_Queue;  -- Using predefined queue

procedure Main is
   protected type Channel is
      procedure Send(Item : in String);
      procedure Receive(Item : out String);
   private
      Queue : Ada.Containers.Financial_Queue.Queue := Ada.Containers.Financial_Queue.Empty_Queue;
      Item_Available : Ada.Synchronous_Task_Control.Suspension_Object;
   end Channel;

   protected body Channel is
      procedure Send(Item : in String) is
      begin
         Queue.Enqueue(Item);
         Ada.Synchronous_Task_Control.Set_True(Item_Available);
      end Send;

      procedure Receive(Item : out String) is
      begin
         Ada.Synchronous_Task_Control.Set_False(Item_Available) when Queue.Is_Empty;
         Queue.Dequeue(Item);
      end Receive;
   end Channel;

   Channel_Instance : Channel;

   task type Sender;
   task type Receiver;
   
   task body Sender is
   begin
      Channel_Instance.Send("ping");
   end Sender;

   task body Receiver is
      Msg : String;
   begin
      Channel_Instance.Receive(Msg);
      Put_Line(Msg);
   end Receiver;

   Sender_Task : Sender;
   Receiver_Task : Receiver;

begin
   null;
end Main;

Sending a Value

Send a value into the channel using the Send procedure. Here we send "ping" to the Channel_Instance from a new task.

Receiving a Value

The Receive procedure receives a value from the channel. Here we receive the "ping" message we sent above and print it out.

Running the Program

When we run the program, the ping message is successfully passed from one task to another via our channel.

$ gnatmake -gnato Main.adb
$ ./main
ping

By default, the send and receive operations on the channel block until both the sender and receiver are ready. This property allows us to ensure synchronization between tasks in our program.