Recent

Author Topic: Threads not working [SOLVED]  (Read 10721 times)

mvampire

  • Jr. Member
  • **
  • Posts: 62
Threads not working [SOLVED]
« on: September 03, 2010, 02:39:33 pm »
I'm trying implement threads in my program.

I made a very simple test program, but it's not working (sometimes print numbers till 50 - 70, not 100, sometimes gives a segmentation fault). I think it's because program terminates before thread finishes it's work:



Code: [Select]
program test;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  cmem,
  pthreads,
  {$ENDIF}{$ENDIF}
  Classes, SysUtils, CustApp, MyThreads
  { you can add units after this };

type

  { TMyApplication }

  TMyApplication = class(TCustomApplication)
  protected
    procedure DoRun; override;
  public
  end;

{ TMyApplication }

procedure TMyApplication.DoRun;
var
 MyThread1: TMyThread;
begin

  { add your program here }
MyThread1:= TMyThread.Create(True);
MyThread1.start:=1;
MyThread1.finish:=100;
MyThread1.Resume;


  // stop program loop
Terminate;
end;

var
  Application: TMyApplication;

{$IFDEF WINDOWS}{$R test.rc}{$ENDIF}

begin
  Application:=TMyApplication.Create(nil);
  Application.Title:='My Application';
  Application.Run;
  Application.Free;
end.



Code: [Select]
unit MyThreads;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils;

 Type
    TMyThread = class(TThread)
    private
    protected
      procedure Execute; override;
    public
      start,finish: integer;
      Constructor Create(CreateSuspended : boolean);
    end;



implementation

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

  procedure TMyThread.Execute;
  var
    i: integer;
  begin
   i:=start;
    while (not Terminated) and (i<=finish) do
      begin
           Writeln(i);
           inc(i);
           if i=finish+1 then Terminate;
      end;
  end;

end.



But I don't know what should I do to make it in the right way...
Please help.

Thank You in advance,
Andrey Sapegin.
« Last Edit: September 10, 2010, 09:37:37 pm by mvampire »

runner

  • New Member
  • *
  • Posts: 12
Re: Threads not working
« Reply #1 on: September 03, 2010, 02:54:59 pm »
Why do you call Application.Free after Application.Run?

Is this a console application? You have problems probably because your application exists before all threads are finished. You have to make sure all threads have finished their work.

Also having more then 5-10 threads is complete overkill and it will slow down you app significantly. Also on almost any system there is a limit to how much threads a single app can have and how much the OS can handle.
« Last Edit: September 03, 2010, 02:57:11 pm by runner »

mvampire

  • Jr. Member
  • **
  • Posts: 62
Re: Threads not working
« Reply #2 on: September 03, 2010, 02:57:25 pm »
Application.Free and other code around was automatically created by Lazarus...

What should I do to make sure all threads have finished their work??

rsling

  • Newbie
  • Posts: 2
Re: Threads not working
« Reply #3 on: September 03, 2010, 03:22:21 pm »
Application.Free and other code around was automatically created by Lazarus...

What should I do to make sure all threads have finished their work??

Application.Free is fine where it is. The problem is rather that you don't have an actual program loop in TMyApplication.DoRun, you just start your threads there. Do something there and only stop doing it until all threads are terminated. Minimally:

Code: [Select]
procedure TMyApplication.DoRun;
var
 MyThread1: TMyThread;
begin
  MyThread1:= TMyThread.Create(True);
  MyThread1.start:=1;
  MyThread1.finish:=100;
  MyThread1.Resume;
  while not MyThread1.Terminated
  do Sleep(10);
  Terminate;
end;

Btw, maybe you do not want to make your threads a local variable of TMyApplication.DoRun.

Cheers!

mvampire

  • Jr. Member
  • **
  • Posts: 62
Re: Threads not working
« Reply #4 on: September 03, 2010, 03:35:07 pm »
Yes, it was my question how to wait until threads will not finished their work.

Now the problem is that MyThread1 has no property Terminated.

So string
Code: [Select]
while not MyThread1.Terminated do Sleep(10);
gives the following compilation error:

test.lpr(37,21) Error: identifier idents no member "Terminated"

rsling

  • Newbie
  • Posts: 2
Re: Threads not working
« Reply #5 on: September 03, 2010, 03:56:05 pm »
test.lpr(37,21) Error: identifier idents no member "Terminated"

Sry, it's protected and thus not visible. Add

Code: [Select]
property Terminated;
into the public section of TMyThread to make it visible in other units. Or move the definition of TMyThread into your main program.
Of course, this is just a hack to make your prog run. The whole thing is of course not a good example of reasonable use and clean implementation of threads ;)

Cheers!
Roland

Marc

  • Administrator
  • Hero Member
  • *
  • Posts: 2671
Re: Threads not working
« Reply #6 on: September 03, 2010, 04:54:11 pm »
Call Terminate. this sets the terminated flag
//--
{$I stdsig.inc}
//-I still can't read someones mind
//-Bugs reported here will be forgotten. Use the bug tracker

mvampire

  • Jr. Member
  • **
  • Posts: 62
Re: Threads not working
« Reply #7 on: September 03, 2010, 11:40:49 pm »
Quote
Of course, this is just a hack to make your prog run. The whole thing is of course not a good example of reasonable use and clean implementation of threads

Thank You very much for Your help! My test program is working now! But can I ask what is a good example?
Can You post it here or send me an e-mail to andrey@sapegin.org?

Really I'm going to use array of threads like here: http://forum.lazarus.freepascal.org/index.php/topic,10399.0.html.
And also in the other program (much bigger and complicated) where each tread will call several procedures and further...

I plan that each thread (and procedures called buy this thread) will read some common global variables but write only to variables allocated specially for this thread...
E.g. if I have 100 threads, they will read some data from global arrays (and receive some values as fields, like threadID), but all they will write, they will write to special array for results [1..100]. E.g., 1 cell of array of record for each thread. Then, after threads will finish their work I will make something with array of results in the main program...
So, I'm going to "manage memory" by myself. Can I ask if it's a right way, or what is a right way, or where I can read about how to implement such situations?

Thank You in advance.

theo

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1933
Re: Threads not working
« Reply #8 on: September 04, 2010, 12:19:21 am »
I plan that each thread (and procedures called buy this thread) will read some common global variables but write only to variables allocated specially for this thread...

I'm not a great specialist on this matter.
I always try to keep threads as simple as possible, which means leave them alone until they have finished.
Of course there is not problem synchronizing them with the main thread for updating the GUI, but it will slow down thread execution.

To your question: Afaik it should be safe to read global variables in threads unless they are written during thread execution by some other thread.
If they are written, use a shared TCriticalSection in all functions which are accesing the "shared" memory.

So your idea doesn't look bad.

« Last Edit: September 04, 2010, 12:23:26 am by theo »

cdbc

  • Hero Member
  • *****
  • Posts: 2572
    • http://www.cdbc.dk
Re: Threads not working
« Reply #9 on: September 04, 2010, 07:43:36 am »
Hi there...
Have a look in the '\lazarusdir\examples\multithreading\waitforunit1.pas'
That's one example on how to wait for a thread.

Another one is here: http://www.midnightbeach.com/jon/pubs/MsgWaits/MsgWaits.html
 - It's written for delphi, but is perfectly useful to get you started with threads in lazarus too.

Lazarus wiki: http://wiki.lazarus.freepascal.org/Multithreaded_Application_Tutorial

google 'threads synchronization lazarus' gets you results too...

for advanced threading have a look at this: http://otl.17slon.com/

Remember Google is your friend :)
Have fun - Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6/QT6 -> FPC Release -> Lazarus Release &  FPC Main -> Lazarus Main

mvampire

  • Jr. Member
  • **
  • Posts: 62
Re: Threads not working
« Reply #10 on: September 07, 2010, 10:16:25 pm »
Thank You all very very much. My program is now working. Problem solved:)

 

TinyPortal © 2005-2018