Channels in Pascal

program Channels;

uses
  SysUtils, Classes;

var
  Messages: TThreadedQueue<string>;
  Msg: string;

procedure SendMessage;
begin
  Messages.PushItem('ping');
end;

begin
  // Create a new queue to act as our channel
  Messages := TThreadedQueue<string>.Create(10, INFINITE, INFINITE);

  // Start a new thread to send a message
  TThread.CreateAnonymousThread(SendMessage).Start;

  // Receive the message from the queue
  Msg := Messages.PopItem;
  WriteLn(Msg);

  // Clean up
  Messages.Free;
end.

Channels in Pascal can be simulated using thread-safe queues. These queues connect concurrent threads. You can send values into queues from one thread and receive those values in another thread.

In this example, we’re using TThreadedQueue<string> from the System.Classes unit to simulate a channel. This queue is thread-safe and can be used for inter-thread communication.

We create a new queue with TThreadedQueue<string>.Create(10, INFINITE, INFINITE). The first parameter (10) is the initial capacity, and the other two parameters set the push and pop timeouts to infinite.

To send a value into the queue, we use the PushItem method. Here we’re sending “ping” to the Messages queue we made above, from a new anonymous thread.

TThread.CreateAnonymousThread(SendMessage).Start;

The PopItem method receives a value from the queue. Here we’ll receive the “ping” message we sent above and print it out.

Msg := Messages.PopItem;
WriteLn(Msg);

When we run the program, the “ping” message is successfully passed from one thread to another via our queue.

$ fpc channels.pas
$ ./channels
ping

By default, PopItem blocks until an item is available in the queue. This property allowed us to wait at the end of our program for the “ping” message without having to use any other synchronization.

Note that in Pascal, we need to manually free the queue at the end of the program to prevent memory leaks.