Thanks Pete,

Even though Micha did manage to explain why my demos ran as they did,
I will try you demo anyway.  Purely to see how big the output file
grows. :-)

Quick recap from Micha.  The time slicing in Linux is much larger that
under Windows.  This improves performance (especially on
calculations).  See the link he posted for a full explanation.  I
modified my Sorting Demo and added three more Bubble Sort threads.
Incremented each threads workload with a lengthy calculation.  This
did the trick to show the time slicing in action.  The first sort
thread fired and worked for about 3 seconds, then the others kicked
in.  :-)  Very different to Windows.

Regards,
 - Graeme -

On 02/10/06, Pete Cervasio <[EMAIL PROTECTED]> wrote:
On Friday 29 September 2006 04:57, Graeme Geldenhuys wrote:
>
> Below is a text (console) thread demo. The one thread counts from 0 to
> 1k and the other thread counts down from 1k to 0.  Again, under Linux,
> one thread executes and teminates, then the next thread executes and
> terminates.

Greetings, Graeme.

I think I see the problem.  On today's fast machines, a count of 1000 just
isn't enough processing for a meaningful test, at least not under Linux.  I
really don't know much about Windows, but my conjecture is that perhaps under
that system the function calls to write the output cause the other thread to
receive processing time.

The following modified version of your program shows that threads work under
Linux.  The execute loops have been modified to continually count up/down (as
appropriate) until terminated.  The RunNow procedure was modified to let the
threads run for three seconds before terminating them itself, and the
FThreadCount thing was taken out (along with the OnTerminate handlers).

To properly see the output, you should redirect it to a file, unless you
really have a LOT of scrollback buffer set up.  :-)  On my Athlon XP 2200 I
get a file 35.5 megabytes in size!

~/tmp $./demo1 > demo1.txt
~/tmp $ls -l demo1.txt
-rw-r--r--  1 pcervasio users 39566886 2006-10-02 12:31 demo1.txt

After looking at the contents of demo1.txt, I can see that the increment
thread actually got to its eleventh count up before the decrement thread got
its first share of time.  This should help explain why in your original
program it appeared that one thread was executing to completion before the
other... it WAS, but only because there wasn't enough to do.

The above was done using version 2.04 of the compiler on a Slackware 10.1
machine with a 2.4.32 kernel.  I appear to get similar results on my 2.6.17.6
box after copying the executable over (running an Athlon 2600).  The
decrementor first shows up after incrementor loop 15.  The redirected output
file is 53 megabytes, though... much bigger than I expected from the machine
speed difference alone.

I hope this is helpful.

Best regards,
Pete C.

---------------------------------------

program demo1a;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}
  {$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}
  {$ENDIF}
  Classes, SysUtils;

type
  // counts up till 1k until terminated
  TIncrementer = class(TThread)
  protected
    procedure Execute; override;
  end;

  // counts down from 1k until terminated
  TDecrementer = class(TThread)
  protected
    procedure Execute; override;
  end;

  TRunThreads = class(TObject)
  private
    t1, t2: TThread;
  public
    constructor Create;
    procedure RunNow;
  end;


{ TRunThreads }

constructor TRunThreads.Create;
begin

  t1 := TIncrementer.Create(True);
  t1.Priority := tpLower;
  t1.FreeOnTerminate := True;

  t2 := TDecrementer.Create(True);
  t2.Priority := tpLower;
  t2.FreeOnTerminate := True;
end;


procedure TRunThreads.RunNow;
var
  donetime: TDateTime;
begin
  { run for 3 seconds }
  donetime := now + encodetime(0, 0, 3, 0);
  writeln('RunNow');
  t1.Resume;
  t2.Resume;
  repeat
    sleep (100);
  until now > donetime;
  t1.terminate;
  t2.terminate;
  sleep (10); { give threads a chance to end }
  WriteLn('All threads completed!');
end;

{ TIncrementer }

procedure TIncrementer.Execute;
var
  i, j: integer;
begin
  j := 0;
  while not terminated do
  begin
    writeln (ClassName, ': --- Loop ', j);
    for i := 0 to 1000 do
    begin
      if terminated then break;
      Writeln(Classname, ': ', i);
    end;
  end;
end;

{ TDecrementer }

procedure TDecrementer.Execute;
var
  i, j: integer;
begin
  j := 0;
  while not terminated do
  begin
    writeln (ClassName, ': --- Loop ', j);
    for i := 1000 downto 0 do
    begin
      if terminated then break;
      Writeln(Classname, ': ', i);
    end;
  end;
end;


var
  lRunThreads: TRunThreads;

begin
  lRunThreads := TRunThreads.Create;
  lRunThreads.RunNow;
  writeln('Done...');
end.

---------------------------------------
_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal



--
There's no place like 127.0.0.1
_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply via email to