Search code examples
linuxmultithreadinglazarus

Threads on Lazarus Linux Ubuntu


I'm having problems when I run an application using threads, on windows works fine, but when I run it on Linux Ubuntu 12.04 my app crashes.

It's a very small app just to understand threads.

when the thread is created my app crashes.

here is the code:

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ComCtrls;

type

{ TMyThread }

  TMyThread = class(TThread)
  private
    fStatusText: string;
    procedure CambiaLabel();
  protected
    procedure Execute; override;
  public
    constructor Create(CreateSuspended: boolean);
  end;

{ TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Label1: TLabel;
    ProgressBar1: TProgressBar;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);

    procedure FormCreate(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
     miHilo: TThread;
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TMyThread }
procedure TMyThread.CambiaLabel();
begin
    Form1.Label1.Caption:=fStatusText;

    Form1.ProgressBar1.StepIt;

    if Form1.ProgressBar1.Position = Form1.ProgressBar1.Max then begin
       Form1.miHilo.Terminate;
       Form1.ProgressBar1.Position := 0;
    end;
end;

procedure TMyThread.Execute;
var
  newStatus : string;
begin
  fStatusText := 'TMyThread comenzando...';
  fStatusText := 'TMyThread Corriendo ...';
  while (not Terminated) and (true {any condition required}) do begin

    //here goes the code of the main thread loop

    Synchronize(@CambiaLabel);

  end;
end;

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

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin

  if miHilo <> nil then begin
    ShowMessage('Ya se esta ejecutando');
  end
  else begin
    miHilo := TMyThread.Create(false);
  end;

end;

procedure TForm1.Button2Click(Sender: TObject);
begin
   if miHilo <> nil then begin
     miHilo.Terminate;
     ShowMessage('Hilo terminado');
     miHilo:=nil;
   end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin

end;

end.

here the images with the error messages: error message image


Solution

  • I found the solution, I was missing something on my .lpr file of my project, I you use threads os OS Unix like Linux, OsX, freebsd, you had to add a line on your .lpr file:

    This is the normal file:

    program project1;
    
    {$mode objfpc}{$H+}
    
    
    uses
      {$IFDEF UNIX}{$IFDEF UseCThreads}
      cthreads,
      {$ENDIF}{$ENDIF}
      Interfaces, // this includes the LCL widgetset
      Forms, Unit1
      { you can add units after this };
      .
      .
      .
    

    and this is the line you have to add {$define UseCThreads}

    so your file should look like this:

    program project1;

    {$mode objfpc}{$H+}
    {$define UseCThreads}
    
    uses
      {$IFDEF UNIX}{$IFDEF UseCThreads}
      cthreads,
      {$ENDIF}{$ENDIF}
      Interfaces, // this includes the LCL widgetset
      Forms, Unit1
      { you can add units after this };
      .
      .
      .
    

    and that's it now works, thanks for the answers and the tips ;D