cli  
Article Series

This article series discuss more than 30 different programming languages. Please read overview before you read any of the details.

Playing with Records Related Articles.

Where to Discuss?

Local Group

Preface

Goal: An overview of multithreading in Free Pascal.

I have used multithreading capability, using TThread about fiteen years ago, but it is limited for windows.

I wonder what option do I have for concurrency in Pascal. Does it have go like channel?

And I finally find the answer. Free Pascal is still using TThread, as main option. But this time works with Linux.


13: Pure FPC Example

My first option is, the pure FPC example.

Official Documentation

This article is my exploration of the official documentation:

Actually I have trouble following this documentation. So I put a few tricks from the forum to solve the problem.

Using CThread in Linux

The official documentation state clearly for unix or linux user, you need this ifdef directive.

Program ThreadTest;

uses
  {$ifdef unix}CThreads, {$endif} SysUtils;

Pascal: Thread Tes: Function

Windows user should pay attention to this, since I omit the directive, after the next example.

Conversion Issue

While compiling, I face this warning:

Warning: Conversion between ordinals and pointers is not portable.

 fpc 31-thread-test
Free Pascal Compiler version 3.2.2 [2022/03/02] for x86_64
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling 31-thread-test.pp
31-thread-test.pp(20,21) Warning: Conversion between ordinals and pointers is not portable
31-thread-test.pp(24,23) Warning: Conversion between ordinals and pointers is not portable
31-thread-test.pp(27,21) Warning: Conversion between ordinals and pointers is not portable
31-thread-test.pp(39,21) Warning: Conversion between ordinals and pointers is not portable
Linking 31-thread-test
43 lines compiled, 0.2 sec
4 warning(s) issued

Pascal: FPC Warning: Conversion Not Portable

Just warning, but pretty annoying.

Quick and Dirty Solution

For this to work, I use directive to surpress the warning message. It means, the problem is still persist in the code.

{$hints off}{$warnings off}
  Writeln('thread ',longint(p),' started');
  thri:=0;
  while (thri<stringlen) do begin
    s:=s+'1'; { create a delay }
    writeln('thread ',longint(p),' thri ',thri,' Len(S)= ',length(s));
    inc(thri);
  end;
  Writeln('thread ',longint(p),' finished');
  InterLockedIncrement(finished);
  f:=0;
{$hints on}{$warnings on}

Pascal: Thread Tes: Function

And also the main program entry point.

Begin
   finished:=0;

   {$hints off}{$warnings off}
   for i:=1 to threadcount do
     BeginThread(@f,pointer(i));
   {$hints on}{$warnings on}

   while finished<threadcount do ;
   Writeln(finished);
End.

The Result

Enjoy the output:

❯ ./31-thread-test
thread 1 started
thread 2 started
thread 1 thri 0 Len(S)= 1
thread 2 thri 0 Len(S)= 1
thread 3 started
thread 3 thri 0 Len(S)= 1
thread 1 thri 1 Len(S)= 2
thread 1 thri 2 Len(S)= 3
...

The example from official documentation is actually works.

Linking Issue

However, this is not the last warning I found.

“crtbeginS.o” not found, this will probably cause a linking failure.

“crtendS.o” not found, this will probably cause a linking failure.

I must have been mad, but I thought the code won’t run. It got me frustrated fo a while. Until I realize it is just a warning. And the code run well.

 fpc 31-thread-test
Free Pascal Compiler version 3.2.2 [2022/03/02] for x86_64
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling 31-thread-test.pp
Linking 31-thread-test
31-thread-test.pp(47,1) Warning: "crtbeginS.o" not found, this will probably cause a linking failure
31-thread-test.pp(47,1) Warning: "crtendS.o" not found, this will probably cause a linking failure
47 lines compiled, 0.2 sec
2 warning(s) issued

Pascal: FPC Warning: Conversion Not Portable

Now, how to get rid of the warning?

Checking Library

I have checked my system, and the library is there.

❯ ls /usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0 "crt*"
32	     crtendS.o	    libgcc.a
cc1	     crtfastmath.o  libgcc_eh.a
cc1plus      crtprec32.o    libgcov.a
collect2     crtprec64.o    liblto_plugin.so
crtbegin.o   crtprec80.o    lto1
crtbeginS.o  include	    lto-wrapper
crtbeginT.o  include-fixed  plugin
crtend.o     install-tools

Pascal: Checking Library

So the issue should lies in the configuration.

FPC Configuration

And I finally found that, the path didn’t match the configuration file. All I need just to alter the configuration file.

# path to the gcclib
#ifdef cpui386
-Fl/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/32
#endif
#ifdef cpux86_64
-Fl/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0
#endif

Pascal: FPC Configuration:

And voila! Nomore FPC warning.


TThread

Most of the code here, I just copy and paste from the official documentation. And reduce things I don’t need.

Official Documentation

Introducing TThread.

You’d better read this first before continue.

MyThread Interface

For convenience, I made an example class in its own unit. So we can change later easier.

{$mode objFPC}
unit MyThread;

interface
Uses CThreads, Classes;

type
  TMyThread = class(TThread)
  protected
    procedure Execute; override;
  public
    Constructor Create(CreateSuspended : boolean);
  end;

Pascal: MyThread: Interface

MyThread Implementation

The implementation is, short.

implementation

constructor TMyThread.Create(CreateSuspended : boolean);
begin
  inherited Create(CreateSuspended);
  FreeOnTerminate := True;
end;

procedure TMyThread.Execute;
begin
  WriteLn('In thread');
end;

end.

Pascal: MyThread: Implementation

Just that short, really. All we need is tell the execute method what to do.

Using MyThread

Now it is time to see the Thread in action. Nothing fancy here. Except, it just run in CLI, without bothering with GUI or such IDE.

uses MyThread;

var
  AThread : TMyThread;
begin
  // This way it doesn't start automatically
  AThread := TMyThread.Create(True); 
  AThread.Start;
end.

We are using AThread.Start to start the thread. With the result similar as below:

❯ ./32-tthread
In thread

Pascal: MyThread: Using The Unit

Wait? Just that output? Where is the concurrency anyway?

Well, for this step, all you need to know is that TThread works in CLI. Whether in linux or windows.

We are going to explore more.


What is Next 🤔?

We are going to go deeper with TThread in CLI.

Consider continue reading [ Pascal - Playing with Records - Part Six ].