Recent

Author Topic: Error multithreading  (Read 356 times)

xinyiman

  • Hero Member
  • *****
  • Posts: 2034
    • Lazarus and Free Pascal italian community
Error multithreading
« on: December 12, 2019, 10:51:57 pm »
Hi guys, I have a problem with a multithreaded program. I found the problem on linux. Practically when effect the following command

EnterCriticalSection (Form1.AThreadCriticalSection);

raises an exception (see image attached).

The version of lazarus / fpc is: Lazarus 2.1.0 r62324M FPC 3.2.0 x86_64-linux-gtk2

Idea?!
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

xinyiman

  • Hero Member
  • *****
  • Posts: 2034
    • Lazarus and Free Pascal italian community
Re: Error multithreading
« Reply #1 on: December 12, 2019, 10:52:57 pm »
One more thing, the same source in console application mode works correctly.
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

jamie

  • Hero Member
  • *****
  • Posts: 2264
Re: Error multithreading
« Reply #2 on: December 12, 2019, 11:26:32 pm »
You should not be using variables from a class like that for a critical section..

 Use a global variable instead;

 The reason for that is when other threads attempt to enter that they will get into the body of the class to
perform the test. You don't want it to be in the body of the class..

 Further more,  you should be using Synchronize method calls instead if you are going to be accessing items like that in the main thread.

Number 1 at blue screen app creations!

xinyiman

  • Hero Member
  • *****
  • Posts: 2034
    • Lazarus and Free Pascal italian community
Re: Error multithreading
« Reply #3 on: December 13, 2019, 08:39:20 am »
Sorry but I didn't understand your answer. The code if executed as application console works well, but if it is executed by a form it goes into error. The critical section is initialized and correctly declared as the variables it uses (all public) in the form1. I knew that the trials in lazarus were communicated in this way.
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

PascalDragon

  • Hero Member
  • *****
  • Posts: 905
  • Compiler Developer
Re: Error multithreading
« Reply #4 on: December 13, 2019, 09:10:18 am »
Where do you call EnterCriticalSection(Form1.AThreadCriticalSection)? Is Form1 instantiated and valid? Where is your critical section instantiated?

MarkMLl

  • Hero Member
  • *****
  • Posts: 610
Re: Error multithreading
« Reply #5 on: December 13, 2019, 09:24:44 am »
Is the critical section object being created?

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.

xinyiman

  • Hero Member
  • *****
  • Posts: 2034
    • Lazarus and Free Pascal italian community
Re: Error multithreading
« Reply #6 on: December 13, 2019, 09:44:44 am »
Code: Pascal  [Select]
  1. TForm1 = class(TForm)
  2. public
  3.          AThreadCriticalSection      : TRTLCriticalSection;
  4.          ThreadMyMessage             : string;
  5.  
       

Code: Pascal  [Select]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. begin
  3.         InitCriticalSection(AThreadCriticalSection);
  4. end;
  5.  

Code: Pascal  [Select]
  1. procedure TForm1.FormDestroy(Sender: TObject);
  2. begin
  3.      DoneCriticalsection(AThreadCriticalSection);
  4. end;
  5.  

And then my code is launched in a timer started once only inside the form show.
Code: Pascal  [Select]
  1.                    app:=TMyThread.create();
  2.                    app.FreeOnTerminate:=true;
  3.                    app.Start;
  4.  
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

xinyiman

  • Hero Member
  • *****
  • Posts: 2034
    • Lazarus and Free Pascal italian community
Re: Error multithreading
« Reply #7 on: December 13, 2019, 11:04:27 am »
The program if compiled on Mac OS X works well. It seems that the problem only occurs if I compile on ubuntu (I use version 19.10)
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

devEric69

  • Full Member
  • ***
  • Posts: 230
Re: Error multithreading
« Reply #8 on: December 13, 2019, 12:35:47 pm »
Hello (you don't show enough to understand what's wrong; maybe you should post a mini-project that reproduces your problem),

1°) you can encapsulate a TCriticalSection (of code), in a field of your TForm (even if the critical sections are global objects provided by the OS).
2°) you can create and destroy your critical section, in your FormCreate and FormDestroy events.
3°) you must, of course, then protect a part of your source code from "race conditions" between threads, with a call to FoCriticalSection.Enter and a call to FoCriticalSection.Leave;

==> If you want to see an example of using a critical code section, which works under Ubuntu, I advise you to read the Multilog package, and especially the MultiLog.pas unit. It uses the FCL TCriticalSection class, that encapsulates the CriticalSection object's API of the OS.
« Last Edit: December 13, 2019, 12:38:36 pm by devEric69 »
use: Linux 64 bits (Ubuntu 18.04 LTS).
Lazarus version: 2.0.4 (svn revision: 62502M) compiled with fpc 3.0.4 - fpDebug \ Dwarf3.