mirror of
				https://gitlab.com/freepascal.org/lazarus/lazarus.git
				synced 2025-11-04 12:29:27 +01:00 
			
		
		
		
	added multithreading examples
git-svn-id: trunk@9575 -
This commit is contained in:
		
							parent
							
								
									41947d6c28
								
							
						
					
					
						commit
						f10441b47f
					
				
							
								
								
									
										15
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							@ -994,11 +994,26 @@ examples/memotest.lpi svneol=native#text/plain
 | 
			
		||||
examples/memotest.pp svneol=native#text/pascal
 | 
			
		||||
examples/messagedialogs.lpi svneol=native#text/plain
 | 
			
		||||
examples/messagedialogs.pp svneol=native#text/pascal
 | 
			
		||||
examples/multithreading/criticalsectionexample1.lpi svneol=native#text/plain
 | 
			
		||||
examples/multithreading/criticalsectionexample1.lpr svneol=native#text/plain
 | 
			
		||||
examples/multithreading/criticalsectionunit1.lfm svneol=native#text/plain
 | 
			
		||||
examples/multithreading/criticalsectionunit1.lrs svneol=native#text/plain
 | 
			
		||||
examples/multithreading/criticalsectionunit1.pas svneol=native#text/plain
 | 
			
		||||
examples/multithreading/mainunit.lfm svneol=native#text/plain
 | 
			
		||||
examples/multithreading/mainunit.lrs svneol=native#text/plain
 | 
			
		||||
examples/multithreading/mainunit.pas svneol=native#text/plain
 | 
			
		||||
examples/multithreading/multithreadingexample1.lpi svneol=native#text/plain
 | 
			
		||||
examples/multithreading/multithreadingexample1.lpr svneol=native#text/plain
 | 
			
		||||
examples/multithreading/processmessagesunit1.lfm svneol=native#text/plain
 | 
			
		||||
examples/multithreading/processmessagesunit1.lrs svneol=native#text/plain
 | 
			
		||||
examples/multithreading/processmessagesunit1.pas svneol=native#text/plain
 | 
			
		||||
examples/multithreading/singlethreadingexample1.lpi svneol=native#text/plain
 | 
			
		||||
examples/multithreading/singlethreadingexample1.lpr svneol=native#text/plain
 | 
			
		||||
examples/multithreading/waitforexample1.lpi svneol=native#text/plain
 | 
			
		||||
examples/multithreading/waitforexample1.lpr svneol=native#text/plain
 | 
			
		||||
examples/multithreading/waitforunit1.lfm svneol=native#text/plain
 | 
			
		||||
examples/multithreading/waitforunit1.lrs svneol=native#text/plain
 | 
			
		||||
examples/multithreading/waitforunit1.pas svneol=native#text/plain
 | 
			
		||||
examples/notebk.lpi svneol=native#text/plain
 | 
			
		||||
examples/notebk.pp svneol=native#text/pascal
 | 
			
		||||
examples/notebku.pp svneol=native#text/pascal
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										62
									
								
								examples/multithreading/criticalsectionexample1.lpi
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								examples/multithreading/criticalsectionexample1.lpi
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,62 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<CONFIG>
 | 
			
		||||
  <ProjectOptions>
 | 
			
		||||
    <PathDelim Value="/"/>
 | 
			
		||||
    <Version Value="5"/>
 | 
			
		||||
    <General>
 | 
			
		||||
      <SessionStorage Value="InProjectDir"/>
 | 
			
		||||
      <MainUnit Value="0"/>
 | 
			
		||||
      <TargetFileExt Value=""/>
 | 
			
		||||
    </General>
 | 
			
		||||
    <PublishOptions>
 | 
			
		||||
      <Version Value="2"/>
 | 
			
		||||
      <IgnoreBinaries Value="False"/>
 | 
			
		||||
      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
 | 
			
		||||
      <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/>
 | 
			
		||||
    </PublishOptions>
 | 
			
		||||
    <RunParams>
 | 
			
		||||
      <local>
 | 
			
		||||
        <FormatVersion Value="1"/>
 | 
			
		||||
        <LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
 | 
			
		||||
      </local>
 | 
			
		||||
    </RunParams>
 | 
			
		||||
    <RequiredPackages Count="1">
 | 
			
		||||
      <Item1>
 | 
			
		||||
        <PackageName Value="LCL"/>
 | 
			
		||||
      </Item1>
 | 
			
		||||
    </RequiredPackages>
 | 
			
		||||
    <Units Count="2">
 | 
			
		||||
      <Unit0>
 | 
			
		||||
        <Filename Value="criticalsectionexample1.lpr"/>
 | 
			
		||||
        <IsPartOfProject Value="True"/>
 | 
			
		||||
        <UnitName Value="CriticalSectionExample1"/>
 | 
			
		||||
      </Unit0>
 | 
			
		||||
      <Unit1>
 | 
			
		||||
        <Filename Value="criticalsectionunit1.pas"/>
 | 
			
		||||
        <ComponentName Value="Form1"/>
 | 
			
		||||
        <IsPartOfProject Value="True"/>
 | 
			
		||||
        <ResourceFilename Value="criticalsectionunit1.lrs"/>
 | 
			
		||||
        <UnitName Value="CriticalSectionUnit1"/>
 | 
			
		||||
      </Unit1>
 | 
			
		||||
    </Units>
 | 
			
		||||
  </ProjectOptions>
 | 
			
		||||
  <CompilerOptions>
 | 
			
		||||
    <Version Value="5"/>
 | 
			
		||||
    <SearchPaths>
 | 
			
		||||
      <SrcPath Value="$(LazarusDir)/lcl/;$(LazarusDir)/lcl/interfaces/$(LCLWidgetType)/"/>
 | 
			
		||||
    </SearchPaths>
 | 
			
		||||
    <CodeGeneration>
 | 
			
		||||
      <Generate Value="Faster"/>
 | 
			
		||||
    </CodeGeneration>
 | 
			
		||||
    <Linking>
 | 
			
		||||
      <Options>
 | 
			
		||||
        <Win32>
 | 
			
		||||
          <GraphicApplication Value="True"/>
 | 
			
		||||
        </Win32>
 | 
			
		||||
      </Options>
 | 
			
		||||
    </Linking>
 | 
			
		||||
    <Other>
 | 
			
		||||
      <CompilerPath Value="$(CompPath)"/>
 | 
			
		||||
    </Other>
 | 
			
		||||
  </CompilerOptions>
 | 
			
		||||
</CONFIG>
 | 
			
		||||
							
								
								
									
										18
									
								
								examples/multithreading/criticalsectionexample1.lpr
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								examples/multithreading/criticalsectionexample1.lpr
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
			
		||||
program CriticalSectionExample1;
 | 
			
		||||
 | 
			
		||||
{$mode objfpc}{$H+}
 | 
			
		||||
 | 
			
		||||
uses
 | 
			
		||||
  {$IFDEF UNIX}
 | 
			
		||||
  cthreads,
 | 
			
		||||
  {$ENDIF}
 | 
			
		||||
  Interfaces, // this includes the LCL widgetset
 | 
			
		||||
  Forms
 | 
			
		||||
  { add your units here }, CriticalSectionUnit1;
 | 
			
		||||
 | 
			
		||||
begin
 | 
			
		||||
  Application.Initialize;
 | 
			
		||||
  Application.CreateForm(TForm1, Form1);
 | 
			
		||||
  Application.Run;
 | 
			
		||||
end.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										43
									
								
								examples/multithreading/criticalsectionunit1.lfm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								examples/multithreading/criticalsectionunit1.lfm
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,43 @@
 | 
			
		||||
object Form1: TForm1
 | 
			
		||||
  Caption = 'Form1'
 | 
			
		||||
  ClientHeight = 169
 | 
			
		||||
  ClientWidth = 312
 | 
			
		||||
  PixelsPerInch = 75
 | 
			
		||||
  HorzScrollBar.Page = 311
 | 
			
		||||
  VertScrollBar.Page = 168
 | 
			
		||||
  Left = 286
 | 
			
		||||
  Height = 169
 | 
			
		||||
  Top = 202
 | 
			
		||||
  Width = 312
 | 
			
		||||
  object Label1: TLabel
 | 
			
		||||
    Caption = 'Label1'
 | 
			
		||||
    Color = clNone
 | 
			
		||||
    ParentColor = False
 | 
			
		||||
    Left = 43
 | 
			
		||||
    Height = 17
 | 
			
		||||
    Top = 125
 | 
			
		||||
    Width = 65
 | 
			
		||||
  end
 | 
			
		||||
  object CountWithCritSecButton: TButton
 | 
			
		||||
    AutoSize = True
 | 
			
		||||
    BorderSpacing.InnerBorder = 4
 | 
			
		||||
    Caption = 'Count with critical section'
 | 
			
		||||
    OnClick = CountWithCritSecButtonClick
 | 
			
		||||
    TabOrder = 0
 | 
			
		||||
    Left = 40
 | 
			
		||||
    Height = 26
 | 
			
		||||
    Top = 24
 | 
			
		||||
    Width = 158
 | 
			
		||||
  end
 | 
			
		||||
  object CountWithoutCritSecButton: TButton
 | 
			
		||||
    AutoSize = True
 | 
			
		||||
    BorderSpacing.InnerBorder = 4
 | 
			
		||||
    Caption = 'Count without critical section'
 | 
			
		||||
    OnClick = CountWithoutCritSecButtonClick
 | 
			
		||||
    TabOrder = 1
 | 
			
		||||
    Left = 40
 | 
			
		||||
    Height = 26
 | 
			
		||||
    Top = 64
 | 
			
		||||
    Width = 175
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										16
									
								
								examples/multithreading/criticalsectionunit1.lrs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								examples/multithreading/criticalsectionunit1.lrs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
			
		||||
{ Dies ist eine automatisch erzeugte Lazarus-Ressourcendatei }
 | 
			
		||||
 | 
			
		||||
LazarusResources.Add('TForm1','FORMDATA',[
 | 
			
		||||
  'TPF0'#6'TForm1'#5'Form1'#7'Caption'#6#5'Form1'#12'ClientHeight'#3#169#0#11'C'
 | 
			
		||||
  +'lientWidth'#3'8'#1#13'PixelsPerInch'#2'K'#18'HorzScrollBar.Page'#3'7'#1#18
 | 
			
		||||
  +'VertScrollBar.Page'#3#168#0#4'Left'#3#30#1#6'Height'#3#169#0#3'Top'#3#202#0
 | 
			
		||||
  +#5'Width'#3'8'#1#0#6'TLabel'#6'Label1'#7'Caption'#6#6'Label1'#5'Color'#7#6'c'
 | 
			
		||||
  +'lNone'#11'ParentColor'#8#4'Left'#2'+'#6'Height'#2#17#3'Top'#2'}'#5'Width'#2
 | 
			
		||||
  +'A'#0#0#7'TButton'#22'CountWithCritSecButton'#8'AutoSize'#9#25'BorderSpacing'
 | 
			
		||||
  +'.InnerBorder'#2#4#7'Caption'#6#27'Count with critical section'#7'OnClick'#7
 | 
			
		||||
  +#27'CountWithCritSecButtonClick'#8'TabOrder'#2#0#4'Left'#2'('#6'Height'#2#26
 | 
			
		||||
  +#3'Top'#2#24#5'Width'#3#158#0#0#0#7'TButton'#25'CountWithoutCritSecButton'#8
 | 
			
		||||
  +'AutoSize'#9#25'BorderSpacing.InnerBorder'#2#4#7'Caption'#6#30'Count without'
 | 
			
		||||
  +' critical section'#7'OnClick'#7#30'CountWithoutCritSecButtonClick'#8'TabOrd'
 | 
			
		||||
  +'er'#2#1#4'Left'#2'('#6'Height'#2#26#3'Top'#2'@'#5'Width'#3#175#0#0#0#0
 | 
			
		||||
]);
 | 
			
		||||
							
								
								
									
										147
									
								
								examples/multithreading/criticalsectionunit1.pas
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								examples/multithreading/criticalsectionunit1.pas
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,147 @@
 | 
			
		||||
{
 | 
			
		||||
 ***************************************************************************
 | 
			
		||||
 *                                                                         *
 | 
			
		||||
 *   This source is free software; you can redistribute it and/or modify   *
 | 
			
		||||
 *   it under the terms of the GNU General Public License as published by  *
 | 
			
		||||
 *   the Free Software Foundation; either version 2 of the License, or     *
 | 
			
		||||
 *   (at your option) any later version.                                   *
 | 
			
		||||
 *                                                                         *
 | 
			
		||||
 *   This code is distributed in the hope that it will be useful, but      *
 | 
			
		||||
 *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
 | 
			
		||||
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
 | 
			
		||||
 *   General Public License for more details.                              *
 | 
			
		||||
 *                                                                         *
 | 
			
		||||
 *   A copy of the GNU General Public License is available on the World    *
 | 
			
		||||
 *   Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also      *
 | 
			
		||||
 *   obtain it by writing to the Free Software Foundation,                 *
 | 
			
		||||
 *   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.        *
 | 
			
		||||
 *                                                                         *
 | 
			
		||||
 ***************************************************************************
 | 
			
		||||
 | 
			
		||||
  Abstract:
 | 
			
		||||
    Demo to show how 5 threads increases a counter.
 | 
			
		||||
    With and without critical sections.
 | 
			
		||||
    
 | 
			
		||||
    With critical sections you will always get 50000.
 | 
			
		||||
    Without you will see different results on each run and depending on your
 | 
			
		||||
    system.
 | 
			
		||||
}
 | 
			
		||||
unit CriticalSectionUnit1;
 | 
			
		||||
 | 
			
		||||
{$mode objfpc}{$H+}
 | 
			
		||||
 | 
			
		||||
interface
 | 
			
		||||
 | 
			
		||||
uses
 | 
			
		||||
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, Buttons,
 | 
			
		||||
  StdCtrls, LCLProc, LCLType, LCLIntf;
 | 
			
		||||
 | 
			
		||||
type
 | 
			
		||||
 | 
			
		||||
  { TMyThread }
 | 
			
		||||
 | 
			
		||||
  TMyThread = class(TThread)
 | 
			
		||||
  public
 | 
			
		||||
    procedure Execute; override;
 | 
			
		||||
    property Finished: boolean read FFinished write FFinished;
 | 
			
		||||
  end;
 | 
			
		||||
 | 
			
		||||
  { TForm1 }
 | 
			
		||||
 | 
			
		||||
  TForm1 = class(TForm)
 | 
			
		||||
    CountWithoutCritSecButton: TButton;
 | 
			
		||||
    CountWithCritSecButton: TButton;
 | 
			
		||||
    Label1: TLabel;
 | 
			
		||||
    procedure CountWithCritSecButtonClick(Sender: TObject);
 | 
			
		||||
    procedure CountWithoutCritSecButtonClick(Sender: TObject);
 | 
			
		||||
  private
 | 
			
		||||
  public
 | 
			
		||||
    CriticalSection: TCriticalSection;
 | 
			
		||||
    Counter: integer;
 | 
			
		||||
    UseCriticalSection: boolean;
 | 
			
		||||
    procedure DoCounting;
 | 
			
		||||
  end; 
 | 
			
		||||
 | 
			
		||||
var
 | 
			
		||||
  Form1: TForm1; 
 | 
			
		||||
 | 
			
		||||
implementation
 | 
			
		||||
 | 
			
		||||
{ TForm1 }
 | 
			
		||||
 | 
			
		||||
procedure TForm1.CountWithCritSecButtonClick(Sender: TObject);
 | 
			
		||||
begin
 | 
			
		||||
  UseCriticalSection:=true;
 | 
			
		||||
  DoCounting;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
procedure TForm1.CountWithoutCritSecButtonClick(Sender: TObject);
 | 
			
		||||
begin
 | 
			
		||||
  UseCriticalSection:=false;
 | 
			
		||||
  DoCounting;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
procedure TForm1.DoCounting;
 | 
			
		||||
var
 | 
			
		||||
  i: Integer;
 | 
			
		||||
  Threads: array[1..5] of TMyThread;
 | 
			
		||||
  AllFinished: Boolean;
 | 
			
		||||
begin
 | 
			
		||||
  Counter:=0;
 | 
			
		||||
  
 | 
			
		||||
  // create the CriticalSection
 | 
			
		||||
  InitializeCriticalSection(CriticalSection);
 | 
			
		||||
 | 
			
		||||
  // start 5 threads
 | 
			
		||||
  for i:=Low(Threads) to High(Threads) do
 | 
			
		||||
    Threads[i]:=TMyThread.Create(false);
 | 
			
		||||
  // wait till all threads finished
 | 
			
		||||
  repeat
 | 
			
		||||
    AllFinished:=true;
 | 
			
		||||
    for i:=Low(Threads) to High(Threads) do
 | 
			
		||||
      if not Threads[i].Finished then AllFinished:=false;
 | 
			
		||||
  until AllFinished;
 | 
			
		||||
  // free the threads
 | 
			
		||||
  for i:=Low(Threads) to High(Threads) do
 | 
			
		||||
    Threads[i].Free;
 | 
			
		||||
 | 
			
		||||
  // free the CriticalSection
 | 
			
		||||
  DeleteCriticalSection(CriticalSection);
 | 
			
		||||
  
 | 
			
		||||
  // show the Counter
 | 
			
		||||
  Label1.Caption:='Counter='+IntToStr(Counter);
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
{ TMyThread }
 | 
			
		||||
 | 
			
		||||
procedure TMyThread.Execute;
 | 
			
		||||
var
 | 
			
		||||
  i: Integer;
 | 
			
		||||
  CurCounter: LongInt;
 | 
			
		||||
  j: Integer;
 | 
			
		||||
begin
 | 
			
		||||
  // increment the counter many times
 | 
			
		||||
  // Because the other threads are doing the same, it will frequently happen,
 | 
			
		||||
  // that 2 (or more) threads read the same number, increment it by one and
 | 
			
		||||
  // write the result back, overwriting the result of the other threads.
 | 
			
		||||
  for i:=1 to 100000 do begin
 | 
			
		||||
    if Form1.UseCriticalSection then
 | 
			
		||||
      EnterCriticalSection(Form1.CriticalSection);
 | 
			
		||||
    try
 | 
			
		||||
      CurCounter:=Form1.Counter;
 | 
			
		||||
      for j:=1 to 1000 do ;
 | 
			
		||||
      inc(CurCounter);
 | 
			
		||||
      Form1.Counter:=CurCounter;
 | 
			
		||||
    finally
 | 
			
		||||
      if Form1.UseCriticalSection then
 | 
			
		||||
        LeaveCriticalSection(Form1.CriticalSection);
 | 
			
		||||
    end;
 | 
			
		||||
  end;
 | 
			
		||||
  Finished:=true;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
initialization
 | 
			
		||||
  {$I criticalsectionunit1.lrs}
 | 
			
		||||
 | 
			
		||||
end.
 | 
			
		||||
 | 
			
		||||
@ -17,6 +17,12 @@
 | 
			
		||||
 *   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.        *
 | 
			
		||||
 *                                                                         *
 | 
			
		||||
 ***************************************************************************
 | 
			
		||||
 | 
			
		||||
  Abstract:
 | 
			
		||||
    Demo to show, how to start a thread and how synchronize with the main
 | 
			
		||||
    thread.
 | 
			
		||||
    Important: The cthread unint must be added to the uses section of the .lpr
 | 
			
		||||
               file. See multithreadingexample1.lpr.
 | 
			
		||||
}
 | 
			
		||||
unit MainUnit;
 | 
			
		||||
 | 
			
		||||
@ -60,18 +66,21 @@ procedure TForm1.FormCreate(Sender: TObject);
 | 
			
		||||
var
 | 
			
		||||
  MyThread : TMyThread;
 | 
			
		||||
begin
 | 
			
		||||
   MyThread := TMyThread.Create(True); // This way it doesn't start automatically
 | 
			
		||||
   if Assigned(MyThread.FatalException) then
 | 
			
		||||
     raise MyThread.FatalException;
 | 
			
		||||
  MyThread := TMyThread.Create(True); // With the True parameter it doesn't start automatically
 | 
			
		||||
  if Assigned(MyThread.FatalException) then
 | 
			
		||||
    raise MyThread.FatalException;
 | 
			
		||||
      
 | 
			
		||||
   // Here the code initialises anything required before the threads starts executing
 | 
			
		||||
  // Here the code initialises anything required before the threads starts executing
 | 
			
		||||
 | 
			
		||||
   MyThread.Resume;
 | 
			
		||||
  MyThread.Resume;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
{ TMyThread }
 | 
			
		||||
 | 
			
		||||
procedure TMyThread.ShowStatus;
 | 
			
		||||
// this method is only called by Synchronize(@ShowStatus) and therefore
 | 
			
		||||
// executed by the main thread
 | 
			
		||||
// The main thread can access GUI elements, for example Form1.Caption.
 | 
			
		||||
begin
 | 
			
		||||
  Form1.Caption := fStatusText;
 | 
			
		||||
end;
 | 
			
		||||
@ -80,13 +89,13 @@ procedure TMyThread.Execute;
 | 
			
		||||
var
 | 
			
		||||
  newStatus : string;
 | 
			
		||||
begin
 | 
			
		||||
  fStatusText := 'Starting...';
 | 
			
		||||
  fStatusText := 'TMyThread Starting...';
 | 
			
		||||
  Synchronize(@Showstatus);
 | 
			
		||||
  fStatusText := 'Running...';
 | 
			
		||||
  fStatusText := 'TMyThread Running...';
 | 
			
		||||
  while (not Terminated) and (true {any condition required}) do begin
 | 
			
		||||
 | 
			
		||||
    //here goes the code of the main thread loop
 | 
			
		||||
    newStatus:='Time: '+FormatDateTime('YYYY-MM-DD HH:NN:SS',Now);
 | 
			
		||||
    newStatus:='TMyThread Time: '+FormatDateTime('YYYY-MM-DD HH:NN:SS',Now);
 | 
			
		||||
    
 | 
			
		||||
    if NewStatus <> fStatusText then begin
 | 
			
		||||
      fStatusText := newStatus;
 | 
			
		||||
 | 
			
		||||
@ -6,12 +6,11 @@
 | 
			
		||||
    <General>
 | 
			
		||||
      <SessionStorage Value="InProjectDir"/>
 | 
			
		||||
      <MainUnit Value="0"/>
 | 
			
		||||
      <IconPath Value="./"/>
 | 
			
		||||
      <TargetFileExt Value=""/>
 | 
			
		||||
    </General>
 | 
			
		||||
    <LazDoc Paths=""/>
 | 
			
		||||
    <PublishOptions>
 | 
			
		||||
      <Version Value="2"/>
 | 
			
		||||
      <IgnoreBinaries Value="False"/>
 | 
			
		||||
      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
 | 
			
		||||
      <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/>
 | 
			
		||||
    </PublishOptions>
 | 
			
		||||
 | 
			
		||||
@ -3,12 +3,13 @@ program MultiThreadingExample1;
 | 
			
		||||
{$mode objfpc}{$H+}
 | 
			
		||||
 | 
			
		||||
uses
 | 
			
		||||
  // for multi threading the cthreads unit must be used on unix systems:
 | 
			
		||||
  // for example: Linux, MacOSX, FreeBSD, Solaris
 | 
			
		||||
  {$IFDEF UNIX}
 | 
			
		||||
  cthreads,
 | 
			
		||||
  {$ENDIF}
 | 
			
		||||
  Interfaces, // this includes the LCL widgetset
 | 
			
		||||
  Forms
 | 
			
		||||
  { add your units here }, MainUnit;
 | 
			
		||||
  Forms, MainUnit;
 | 
			
		||||
 | 
			
		||||
begin
 | 
			
		||||
  Application.Initialize;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										34
									
								
								examples/multithreading/processmessagesunit1.lfm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								examples/multithreading/processmessagesunit1.lfm
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,34 @@
 | 
			
		||||
object Form1: TForm1
 | 
			
		||||
  Caption = 'Form1'
 | 
			
		||||
  ClientHeight = 142
 | 
			
		||||
  ClientWidth = 303
 | 
			
		||||
  OnCreate = FormCreate
 | 
			
		||||
  PixelsPerInch = 75
 | 
			
		||||
  HorzScrollBar.Page = 302
 | 
			
		||||
  VertScrollBar.Page = 141
 | 
			
		||||
  Left = 286
 | 
			
		||||
  Height = 142
 | 
			
		||||
  Top = 202
 | 
			
		||||
  Width = 303
 | 
			
		||||
  object StartStopButton: TButton
 | 
			
		||||
    Anchors = [akTop]
 | 
			
		||||
    BorderSpacing.InnerBorder = 4
 | 
			
		||||
    Caption = 'Start'
 | 
			
		||||
    OnClick = StartStopButtonClick
 | 
			
		||||
    TabOrder = 0
 | 
			
		||||
    Left = 72
 | 
			
		||||
    Height = 25
 | 
			
		||||
    Top = 40
 | 
			
		||||
    Width = 158
 | 
			
		||||
  end
 | 
			
		||||
  object ProgressBar1: TProgressBar
 | 
			
		||||
    Anchors = [akTop, akLeft, akRight]
 | 
			
		||||
    Max = 1000
 | 
			
		||||
    Smooth = True
 | 
			
		||||
    Step = 1
 | 
			
		||||
    Left = 32
 | 
			
		||||
    Height = 20
 | 
			
		||||
    Top = 88
 | 
			
		||||
    Width = 244
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										14
									
								
								examples/multithreading/processmessagesunit1.lrs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								examples/multithreading/processmessagesunit1.lrs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
			
		||||
{ Dies ist eine automatisch erzeugte Lazarus-Ressourcendatei }
 | 
			
		||||
 | 
			
		||||
LazarusResources.Add('TForm1','FORMDATA',[
 | 
			
		||||
  'TPF0'#6'TForm1'#5'Form1'#7'Caption'#6#5'Form1'#12'ClientHeight'#3#142#0#11'C'
 | 
			
		||||
  +'lientWidth'#3'/'#1#8'OnCreate'#7#10'FormCreate'#13'PixelsPerInch'#2'K'#18'H'
 | 
			
		||||
  +'orzScrollBar.Page'#3'.'#1#18'VertScrollBar.Page'#3#141#0#4'Left'#3#30#1#6'H'
 | 
			
		||||
  +'eight'#3#142#0#3'Top'#3#202#0#5'Width'#3'/'#1#0#7'TButton'#15'StartStopButt'
 | 
			
		||||
  +'on'#7'Anchors'#11#5'akTop'#0#25'BorderSpacing.InnerBorder'#2#4#7'Caption'#6
 | 
			
		||||
  +#5'Start'#7'OnClick'#7#20'StartStopButtonClick'#8'TabOrder'#2#0#4'Left'#2'H'
 | 
			
		||||
  +#6'Height'#2#25#3'Top'#2'('#5'Width'#3#158#0#0#0#12'TProgressBar'#12'Progres'
 | 
			
		||||
  +'sBar1'#7'Anchors'#11#5'akTop'#6'akLeft'#7'akRight'#0#3'Max'#3#232#3#6'Smoot'
 | 
			
		||||
  +'h'#9#4'Step'#2#1#4'Left'#2' '#6'Height'#2#20#3'Top'#2'X'#5'Width'#3#244#0#0
 | 
			
		||||
  +#0#0
 | 
			
		||||
]);
 | 
			
		||||
							
								
								
									
										138
									
								
								examples/multithreading/processmessagesunit1.pas
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								examples/multithreading/processmessagesunit1.pas
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,138 @@
 | 
			
		||||
{
 | 
			
		||||
 ***************************************************************************
 | 
			
		||||
 *                                                                         *
 | 
			
		||||
 *   This source is free software; you can redistribute it and/or modify   *
 | 
			
		||||
 *   it under the terms of the GNU General Public License as published by  *
 | 
			
		||||
 *   the Free Software Foundation; either version 2 of the License, or     *
 | 
			
		||||
 *   (at your option) any later version.                                   *
 | 
			
		||||
 *                                                                         *
 | 
			
		||||
 *   This code is distributed in the hope that it will be useful, but      *
 | 
			
		||||
 *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
 | 
			
		||||
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
 | 
			
		||||
 *   General Public License for more details.                              *
 | 
			
		||||
 *                                                                         *
 | 
			
		||||
 *   A copy of the GNU General Public License is available on the World    *
 | 
			
		||||
 *   Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also      *
 | 
			
		||||
 *   obtain it by writing to the Free Software Foundation,                 *
 | 
			
		||||
 *   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.        *
 | 
			
		||||
 *                                                                         *
 | 
			
		||||
 ***************************************************************************
 | 
			
		||||
 | 
			
		||||
  Abstract:
 | 
			
		||||
    Demo to show, how to process a big file with the main thread.
 | 
			
		||||
}
 | 
			
		||||
unit ProcessMessagesUnit1;
 | 
			
		||||
 | 
			
		||||
{$mode objfpc}{$H+}
 | 
			
		||||
 | 
			
		||||
interface
 | 
			
		||||
 | 
			
		||||
uses
 | 
			
		||||
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, Buttons,
 | 
			
		||||
  ComCtrls;
 | 
			
		||||
 | 
			
		||||
type
 | 
			
		||||
 | 
			
		||||
  { TForm1 }
 | 
			
		||||
 | 
			
		||||
  TForm1 = class(TForm)
 | 
			
		||||
    ProgressBar1: TProgressBar;
 | 
			
		||||
    StartStopButton: TButton;
 | 
			
		||||
    procedure FormCreate(Sender: TObject);
 | 
			
		||||
    procedure StartStopButtonClick(Sender: TObject);
 | 
			
		||||
  private
 | 
			
		||||
    procedure Run;
 | 
			
		||||
    procedure UpdateButton;
 | 
			
		||||
  public
 | 
			
		||||
    Running: boolean;
 | 
			
		||||
    Aborting: boolean;
 | 
			
		||||
    Filename: String;
 | 
			
		||||
  end;
 | 
			
		||||
 | 
			
		||||
var
 | 
			
		||||
  Form1: TForm1; 
 | 
			
		||||
 | 
			
		||||
implementation
 | 
			
		||||
 | 
			
		||||
{ TForm1 }
 | 
			
		||||
 | 
			
		||||
procedure TForm1.FormCreate(Sender: TObject);
 | 
			
		||||
begin
 | 
			
		||||
  Filename:='processmessagesunit1.pas';
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
procedure TForm1.StartStopButtonClick(Sender: TObject);
 | 
			
		||||
begin
 | 
			
		||||
  if not Running then
 | 
			
		||||
    Run
 | 
			
		||||
  else
 | 
			
		||||
    Aborting:=true;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
procedure TForm1.Run;
 | 
			
		||||
var
 | 
			
		||||
  fs: TFileStream;
 | 
			
		||||
  Buffer: string;
 | 
			
		||||
  Count: LongInt;
 | 
			
		||||
  i: Integer;
 | 
			
		||||
  Last: TDateTime;
 | 
			
		||||
begin
 | 
			
		||||
  if Running then exit;
 | 
			
		||||
  Running:=true;
 | 
			
		||||
  UpdateButton;
 | 
			
		||||
  try
 | 
			
		||||
    // open a file
 | 
			
		||||
    fs:=TFileStream.Create(Filename,fmOpenRead);
 | 
			
		||||
    try
 | 
			
		||||
      SetLength(Buffer,10);
 | 
			
		||||
      while true do begin
 | 
			
		||||
 | 
			
		||||
        // process all user events, like clicking on the button
 | 
			
		||||
        Application.ProcessMessages;
 | 
			
		||||
        if Aborting or Application.Terminated then break;
 | 
			
		||||
 | 
			
		||||
        // read some bytes
 | 
			
		||||
        Count:=fs.Read(Buffer[1],length(Buffer));
 | 
			
		||||
        if Count=0 then break;
 | 
			
		||||
 | 
			
		||||
        // process ...
 | 
			
		||||
        for i:=1 to Count do begin
 | 
			
		||||
          Last:=Now;
 | 
			
		||||
          repeat
 | 
			
		||||
          until Now-Last>(double(1)/fs.Size)/10000;
 | 
			
		||||
        end;
 | 
			
		||||
 | 
			
		||||
        // show progress
 | 
			
		||||
        ProgressBar1.Position:=ProgressBar1.Min
 | 
			
		||||
               +((ProgressBar1.Max-ProgressBar1.Min+1)*fs.Position) div fs.Size;
 | 
			
		||||
      end;
 | 
			
		||||
    finally
 | 
			
		||||
      fs.Free;
 | 
			
		||||
    end;
 | 
			
		||||
  except
 | 
			
		||||
    on E: Exception do begin
 | 
			
		||||
      MessageDlg('Error',E.Message,mtError,[mbCancel],0);
 | 
			
		||||
    end;
 | 
			
		||||
  end;
 | 
			
		||||
  Aborting:=false;
 | 
			
		||||
  Running:=false;
 | 
			
		||||
  UpdateButton;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
procedure TForm1.UpdateButton;
 | 
			
		||||
begin
 | 
			
		||||
  if Running then begin
 | 
			
		||||
    if Aborting then
 | 
			
		||||
      StartStopButton.Caption:='Aborting ...'
 | 
			
		||||
    else
 | 
			
		||||
      StartStopButton.Caption:='Running ...';
 | 
			
		||||
  end else begin
 | 
			
		||||
    StartStopButton.Caption:='Start';
 | 
			
		||||
  end;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
initialization
 | 
			
		||||
  {$I processmessagesunit1.lrs}
 | 
			
		||||
 | 
			
		||||
end.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										63
									
								
								examples/multithreading/singlethreadingexample1.lpi
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								examples/multithreading/singlethreadingexample1.lpi
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,63 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<CONFIG>
 | 
			
		||||
  <ProjectOptions>
 | 
			
		||||
    <PathDelim Value="/"/>
 | 
			
		||||
    <Version Value="5"/>
 | 
			
		||||
    <General>
 | 
			
		||||
      <SessionStorage Value="InProjectDir"/>
 | 
			
		||||
      <MainUnit Value="0"/>
 | 
			
		||||
      <IconPath Value="./"/>
 | 
			
		||||
      <TargetFileExt Value=""/>
 | 
			
		||||
    </General>
 | 
			
		||||
    <PublishOptions>
 | 
			
		||||
      <Version Value="2"/>
 | 
			
		||||
      <IgnoreBinaries Value="False"/>
 | 
			
		||||
      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
 | 
			
		||||
      <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/>
 | 
			
		||||
    </PublishOptions>
 | 
			
		||||
    <RunParams>
 | 
			
		||||
      <local>
 | 
			
		||||
        <FormatVersion Value="1"/>
 | 
			
		||||
        <LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
 | 
			
		||||
      </local>
 | 
			
		||||
    </RunParams>
 | 
			
		||||
    <RequiredPackages Count="1">
 | 
			
		||||
      <Item1>
 | 
			
		||||
        <PackageName Value="LCL"/>
 | 
			
		||||
      </Item1>
 | 
			
		||||
    </RequiredPackages>
 | 
			
		||||
    <Units Count="2">
 | 
			
		||||
      <Unit0>
 | 
			
		||||
        <Filename Value="singlethreadingexample1.lpr"/>
 | 
			
		||||
        <IsPartOfProject Value="True"/>
 | 
			
		||||
        <UnitName Value="SingleThreadingExample1"/>
 | 
			
		||||
      </Unit0>
 | 
			
		||||
      <Unit1>
 | 
			
		||||
        <Filename Value="processmessagesunit1.pas"/>
 | 
			
		||||
        <ComponentName Value="Form1"/>
 | 
			
		||||
        <IsPartOfProject Value="True"/>
 | 
			
		||||
        <ResourceFilename Value="processmessagesunit1.lrs"/>
 | 
			
		||||
        <UnitName Value="ProcessMessagesUnit1"/>
 | 
			
		||||
      </Unit1>
 | 
			
		||||
    </Units>
 | 
			
		||||
  </ProjectOptions>
 | 
			
		||||
  <CompilerOptions>
 | 
			
		||||
    <Version Value="5"/>
 | 
			
		||||
    <SearchPaths>
 | 
			
		||||
      <SrcPath Value="$(LazarusDir)/lcl/;$(LazarusDir)/lcl/interfaces/$(LCLWidgetType)/"/>
 | 
			
		||||
    </SearchPaths>
 | 
			
		||||
    <CodeGeneration>
 | 
			
		||||
      <Generate Value="Faster"/>
 | 
			
		||||
    </CodeGeneration>
 | 
			
		||||
    <Linking>
 | 
			
		||||
      <Options>
 | 
			
		||||
        <Win32>
 | 
			
		||||
          <GraphicApplication Value="True"/>
 | 
			
		||||
        </Win32>
 | 
			
		||||
      </Options>
 | 
			
		||||
    </Linking>
 | 
			
		||||
    <Other>
 | 
			
		||||
      <CompilerPath Value="$(CompPath)"/>
 | 
			
		||||
    </Other>
 | 
			
		||||
  </CompilerOptions>
 | 
			
		||||
</CONFIG>
 | 
			
		||||
							
								
								
									
										18
									
								
								examples/multithreading/singlethreadingexample1.lpr
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								examples/multithreading/singlethreadingexample1.lpr
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
			
		||||
program SingleThreadingExample1;
 | 
			
		||||
 | 
			
		||||
{$mode objfpc}{$H+}
 | 
			
		||||
 | 
			
		||||
uses
 | 
			
		||||
  {$IFDEF UNIX}{$IFDEF UseCThreads}
 | 
			
		||||
  cthreads,
 | 
			
		||||
  {$ENDIF}{$ENDIF}
 | 
			
		||||
  Interfaces, // this includes the LCL widgetset
 | 
			
		||||
  Forms
 | 
			
		||||
  { add your units here }, ProcessMessagesUnit1;
 | 
			
		||||
 | 
			
		||||
begin
 | 
			
		||||
  Application.Initialize;
 | 
			
		||||
  Application.CreateForm(TForm1, Form1);
 | 
			
		||||
  Application.Run;
 | 
			
		||||
end.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										244
									
								
								examples/multithreading/waitforexample1.lpi
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										244
									
								
								examples/multithreading/waitforexample1.lpi
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,244 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<CONFIG>
 | 
			
		||||
  <ProjectOptions>
 | 
			
		||||
    <PathDelim Value="/"/>
 | 
			
		||||
    <Version Value="5"/>
 | 
			
		||||
    <General>
 | 
			
		||||
      <MainUnit Value="0"/>
 | 
			
		||||
      <TargetFileExt Value=""/>
 | 
			
		||||
      <ActiveEditorIndexAtStart Value="0"/>
 | 
			
		||||
    </General>
 | 
			
		||||
    <PublishOptions>
 | 
			
		||||
      <Version Value="2"/>
 | 
			
		||||
      <IgnoreBinaries Value="False"/>
 | 
			
		||||
      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
 | 
			
		||||
      <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/>
 | 
			
		||||
    </PublishOptions>
 | 
			
		||||
    <RunParams>
 | 
			
		||||
      <local>
 | 
			
		||||
        <FormatVersion Value="1"/>
 | 
			
		||||
        <LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
 | 
			
		||||
      </local>
 | 
			
		||||
    </RunParams>
 | 
			
		||||
    <RequiredPackages Count="1">
 | 
			
		||||
      <Item1>
 | 
			
		||||
        <PackageName Value="LCL"/>
 | 
			
		||||
      </Item1>
 | 
			
		||||
    </RequiredPackages>
 | 
			
		||||
    <Units Count="8">
 | 
			
		||||
      <Unit0>
 | 
			
		||||
        <Filename Value="waitforexample1.lpr"/>
 | 
			
		||||
        <IsPartOfProject Value="True"/>
 | 
			
		||||
        <UnitName Value="WaitForExample1"/>
 | 
			
		||||
        <CursorPos X="8" Y="14"/>
 | 
			
		||||
        <TopLine Value="1"/>
 | 
			
		||||
        <EditorIndex Value="1"/>
 | 
			
		||||
        <UsageCount Value="20"/>
 | 
			
		||||
        <Loaded Value="True"/>
 | 
			
		||||
      </Unit0>
 | 
			
		||||
      <Unit1>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <ComponentName Value="Form1"/>
 | 
			
		||||
        <IsPartOfProject Value="True"/>
 | 
			
		||||
        <ResourceFilename Value="waitforunit1.lrs"/>
 | 
			
		||||
        <UnitName Value="WaitForUnit1"/>
 | 
			
		||||
        <CursorPos X="20" Y="32"/>
 | 
			
		||||
        <TopLine Value="1"/>
 | 
			
		||||
        <EditorIndex Value="0"/>
 | 
			
		||||
        <UsageCount Value="20"/>
 | 
			
		||||
        <Loaded Value="True"/>
 | 
			
		||||
      </Unit1>
 | 
			
		||||
      <Unit2>
 | 
			
		||||
        <Filename Value="mainunit.pas"/>
 | 
			
		||||
        <UnitName Value="MainUnit"/>
 | 
			
		||||
        <CursorPos X="1" Y="27"/>
 | 
			
		||||
        <TopLine Value="1"/>
 | 
			
		||||
        <EditorIndex Value="7"/>
 | 
			
		||||
        <UsageCount Value="10"/>
 | 
			
		||||
        <Loaded Value="True"/>
 | 
			
		||||
      </Unit2>
 | 
			
		||||
      <Unit3>
 | 
			
		||||
        <Filename Value="../../../freepascal/fpc/fcl/inc/custapp.pp"/>
 | 
			
		||||
        <UnitName Value="CustApp"/>
 | 
			
		||||
        <CursorPos X="14" Y="69"/>
 | 
			
		||||
        <TopLine Value="47"/>
 | 
			
		||||
        <EditorIndex Value="6"/>
 | 
			
		||||
        <UsageCount Value="10"/>
 | 
			
		||||
        <Loaded Value="True"/>
 | 
			
		||||
      </Unit3>
 | 
			
		||||
      <Unit4>
 | 
			
		||||
        <Filename Value="../../../freepascal/fpc/rtl/objpas/classes/classesh.inc"/>
 | 
			
		||||
        <CursorPos X="18" Y="1220"/>
 | 
			
		||||
        <TopLine Value="1196"/>
 | 
			
		||||
        <EditorIndex Value="3"/>
 | 
			
		||||
        <UsageCount Value="10"/>
 | 
			
		||||
        <Loaded Value="True"/>
 | 
			
		||||
      </Unit4>
 | 
			
		||||
      <Unit5>
 | 
			
		||||
        <Filename Value="../../../freepascal/fpc/rtl/objpas/classes/classes.inc"/>
 | 
			
		||||
        <CursorPos X="1" Y="103"/>
 | 
			
		||||
        <TopLine Value="75"/>
 | 
			
		||||
        <EditorIndex Value="5"/>
 | 
			
		||||
        <UsageCount Value="10"/>
 | 
			
		||||
        <Loaded Value="True"/>
 | 
			
		||||
      </Unit5>
 | 
			
		||||
      <Unit6>
 | 
			
		||||
        <Filename Value="../../../freepascal/fpc/rtl/inc/threadh.inc"/>
 | 
			
		||||
        <CursorPos X="59" Y="136"/>
 | 
			
		||||
        <TopLine Value="110"/>
 | 
			
		||||
        <EditorIndex Value="2"/>
 | 
			
		||||
        <UsageCount Value="10"/>
 | 
			
		||||
        <Loaded Value="True"/>
 | 
			
		||||
      </Unit6>
 | 
			
		||||
      <Unit7>
 | 
			
		||||
        <Filename Value="../../../freepascal/fpc/rtl/linux/tthread.inc"/>
 | 
			
		||||
        <CursorPos X="3" Y="292"/>
 | 
			
		||||
        <TopLine Value="290"/>
 | 
			
		||||
        <EditorIndex Value="4"/>
 | 
			
		||||
        <UsageCount Value="10"/>
 | 
			
		||||
        <Loaded Value="True"/>
 | 
			
		||||
      </Unit7>
 | 
			
		||||
    </Units>
 | 
			
		||||
    <JumpHistory Count="30" HistoryIndex="29">
 | 
			
		||||
      <Position1>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <Caret Line="158" Column="1" TopLine="122"/>
 | 
			
		||||
      </Position1>
 | 
			
		||||
      <Position2>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <Caret Line="112" Column="11" TopLine="90"/>
 | 
			
		||||
      </Position2>
 | 
			
		||||
      <Position3>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <Caret Line="102" Column="1" TopLine="90"/>
 | 
			
		||||
      </Position3>
 | 
			
		||||
      <Position4>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <Caret Line="145" Column="1" TopLine="109"/>
 | 
			
		||||
      </Position4>
 | 
			
		||||
      <Position5>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <Caret Line="45" Column="1" TopLine="45"/>
 | 
			
		||||
      </Position5>
 | 
			
		||||
      <Position6>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <Caret Line="145" Column="19" TopLine="109"/>
 | 
			
		||||
      </Position6>
 | 
			
		||||
      <Position7>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <Caret Line="72" Column="1" TopLine="50"/>
 | 
			
		||||
      </Position7>
 | 
			
		||||
      <Position8>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <Caret Line="144" Column="22" TopLine="108"/>
 | 
			
		||||
      </Position8>
 | 
			
		||||
      <Position9>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <Caret Line="110" Column="5" TopLine="56"/>
 | 
			
		||||
      </Position9>
 | 
			
		||||
      <Position10>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <Caret Line="105" Column="15" TopLine="102"/>
 | 
			
		||||
      </Position10>
 | 
			
		||||
      <Position11>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <Caret Line="76" Column="1" TopLine="54"/>
 | 
			
		||||
      </Position11>
 | 
			
		||||
      <Position12>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <Caret Line="114" Column="8" TopLine="96"/>
 | 
			
		||||
      </Position12>
 | 
			
		||||
      <Position13>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <Caret Line="115" Column="5" TopLine="93"/>
 | 
			
		||||
      </Position13>
 | 
			
		||||
      <Position14>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <Caret Line="53" Column="25" TopLine="26"/>
 | 
			
		||||
      </Position14>
 | 
			
		||||
      <Position15>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <Caret Line="45" Column="25" TopLine="23"/>
 | 
			
		||||
      </Position15>
 | 
			
		||||
      <Position16>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <Caret Line="118" Column="62" TopLine="96"/>
 | 
			
		||||
      </Position16>
 | 
			
		||||
      <Position17>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <Caret Line="133" Column="7" TopLine="111"/>
 | 
			
		||||
      </Position17>
 | 
			
		||||
      <Position18>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <Caret Line="40" Column="36" TopLine="18"/>
 | 
			
		||||
      </Position18>
 | 
			
		||||
      <Position19>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <Caret Line="66" Column="15" TopLine="35"/>
 | 
			
		||||
      </Position19>
 | 
			
		||||
      <Position20>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <Caret Line="133" Column="1" TopLine="101"/>
 | 
			
		||||
      </Position20>
 | 
			
		||||
      <Position21>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <Caret Line="21" Column="1" TopLine="1"/>
 | 
			
		||||
      </Position21>
 | 
			
		||||
      <Position22>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <Caret Line="149" Column="11" TopLine="116"/>
 | 
			
		||||
      </Position22>
 | 
			
		||||
      <Position23>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <Caret Line="71" Column="12" TopLine="49"/>
 | 
			
		||||
      </Position23>
 | 
			
		||||
      <Position24>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <Caret Line="103" Column="38" TopLine="81"/>
 | 
			
		||||
      </Position24>
 | 
			
		||||
      <Position25>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <Caret Line="102" Column="1" TopLine="81"/>
 | 
			
		||||
      </Position25>
 | 
			
		||||
      <Position26>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <Caret Line="148" Column="11" TopLine="115"/>
 | 
			
		||||
      </Position26>
 | 
			
		||||
      <Position27>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <Caret Line="129" Column="5" TopLine="114"/>
 | 
			
		||||
      </Position27>
 | 
			
		||||
      <Position28>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <Caret Line="150" Column="1" TopLine="114"/>
 | 
			
		||||
      </Position28>
 | 
			
		||||
      <Position29>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <Caret Line="147" Column="1" TopLine="116"/>
 | 
			
		||||
      </Position29>
 | 
			
		||||
      <Position30>
 | 
			
		||||
        <Filename Value="waitforunit1.pas"/>
 | 
			
		||||
        <Caret Line="152" Column="3" TopLine="118"/>
 | 
			
		||||
      </Position30>
 | 
			
		||||
    </JumpHistory>
 | 
			
		||||
  </ProjectOptions>
 | 
			
		||||
  <CompilerOptions>
 | 
			
		||||
    <Version Value="5"/>
 | 
			
		||||
    <SearchPaths>
 | 
			
		||||
      <SrcPath Value="$(LazarusDir)/lcl/;$(LazarusDir)/lcl/interfaces/$(LCLWidgetType)/"/>
 | 
			
		||||
    </SearchPaths>
 | 
			
		||||
    <CodeGeneration>
 | 
			
		||||
      <Generate Value="Faster"/>
 | 
			
		||||
    </CodeGeneration>
 | 
			
		||||
    <Linking>
 | 
			
		||||
      <Options>
 | 
			
		||||
        <Win32>
 | 
			
		||||
          <GraphicApplication Value="True"/>
 | 
			
		||||
        </Win32>
 | 
			
		||||
      </Options>
 | 
			
		||||
    </Linking>
 | 
			
		||||
    <Other>
 | 
			
		||||
      <CompilerPath Value="$(CompPath)"/>
 | 
			
		||||
    </Other>
 | 
			
		||||
  </CompilerOptions>
 | 
			
		||||
</CONFIG>
 | 
			
		||||
							
								
								
									
										18
									
								
								examples/multithreading/waitforexample1.lpr
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								examples/multithreading/waitforexample1.lpr
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
			
		||||
program WaitForExample1;
 | 
			
		||||
 | 
			
		||||
{$mode objfpc}{$H+}
 | 
			
		||||
 | 
			
		||||
uses
 | 
			
		||||
  {$IFDEF UNIX}
 | 
			
		||||
  cthreads,
 | 
			
		||||
  {$ENDIF}
 | 
			
		||||
  Interfaces, // this includes the LCL widgetset
 | 
			
		||||
  Forms
 | 
			
		||||
  { add your units here }, WaitForUnit1;
 | 
			
		||||
 | 
			
		||||
begin
 | 
			
		||||
  Application.Initialize;
 | 
			
		||||
  Application.CreateForm(TForm1, Form1);
 | 
			
		||||
  Application.Run;
 | 
			
		||||
end.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										32
									
								
								examples/multithreading/waitforunit1.lfm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								examples/multithreading/waitforunit1.lfm
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,32 @@
 | 
			
		||||
object Form1: TForm1
 | 
			
		||||
  ActiveControl = Button1
 | 
			
		||||
  Caption = 'Form1'
 | 
			
		||||
  ClientHeight = 359
 | 
			
		||||
  ClientWidth = 394
 | 
			
		||||
  OnCreate = FormCreate
 | 
			
		||||
  OnDestroy = FormDestroy
 | 
			
		||||
  PixelsPerInch = 75
 | 
			
		||||
  HorzScrollBar.Page = 393
 | 
			
		||||
  VertScrollBar.Page = 358
 | 
			
		||||
  Left = 286
 | 
			
		||||
  Height = 359
 | 
			
		||||
  Top = 202
 | 
			
		||||
  Width = 394
 | 
			
		||||
  object Button1: TButton
 | 
			
		||||
    BorderSpacing.InnerBorder = 4
 | 
			
		||||
    Caption = 'Start'
 | 
			
		||||
    OnClick = Button1Click
 | 
			
		||||
    TabOrder = 0
 | 
			
		||||
    Left = 32
 | 
			
		||||
    Height = 25
 | 
			
		||||
    Top = 16
 | 
			
		||||
    Width = 75
 | 
			
		||||
  end
 | 
			
		||||
  object Memo1: TMemo
 | 
			
		||||
    Align = alBottom
 | 
			
		||||
    TabOrder = 1
 | 
			
		||||
    Height = 303
 | 
			
		||||
    Top = 56
 | 
			
		||||
    Width = 394
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										13
									
								
								examples/multithreading/waitforunit1.lrs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								examples/multithreading/waitforunit1.lrs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,13 @@
 | 
			
		||||
{ Dies ist eine automatisch erzeugte Lazarus-Ressourcendatei }
 | 
			
		||||
 | 
			
		||||
LazarusResources.Add('TForm1','FORMDATA',[
 | 
			
		||||
  'TPF0'#6'TForm1'#5'Form1'#13'ActiveControl'#7#7'Button1'#7'Caption'#6#5'Form1'
 | 
			
		||||
  +#12'ClientHeight'#3'g'#1#11'ClientWidth'#3#138#1#8'OnCreate'#7#10'FormCreate'
 | 
			
		||||
  +#9'OnDestroy'#7#11'FormDestroy'#13'PixelsPerInch'#2'K'#18'HorzScrollBar.Page'
 | 
			
		||||
  +#3#137#1#18'VertScrollBar.Page'#3'f'#1#4'Left'#3#30#1#6'Height'#3'g'#1#3'Top'
 | 
			
		||||
  +#3#202#0#5'Width'#3#138#1#0#7'TButton'#7'Button1'#25'BorderSpacing.InnerBord'
 | 
			
		||||
  +'er'#2#4#7'Caption'#6#5'Start'#7'OnClick'#7#12'Button1Click'#8'TabOrder'#2#0
 | 
			
		||||
  +#4'Left'#2' '#6'Height'#2#25#3'Top'#2#16#5'Width'#2'K'#0#0#5'TMemo'#5'Memo1'
 | 
			
		||||
  +#5'Align'#7#8'alBottom'#8'TabOrder'#2#1#6'Height'#3'/'#1#3'Top'#2'8'#5'Width'
 | 
			
		||||
  +#3#138#1#0#0#0
 | 
			
		||||
]);
 | 
			
		||||
							
								
								
									
										162
									
								
								examples/multithreading/waitforunit1.pas
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								examples/multithreading/waitforunit1.pas
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,162 @@
 | 
			
		||||
{
 | 
			
		||||
 ***************************************************************************
 | 
			
		||||
 *                                                                         *
 | 
			
		||||
 *   This source is free software; you can redistribute it and/or modify   *
 | 
			
		||||
 *   it under the terms of the GNU General Public License as published by  *
 | 
			
		||||
 *   the Free Software Foundation; either version 2 of the License, or     *
 | 
			
		||||
 *   (at your option) any later version.                                   *
 | 
			
		||||
 *                                                                         *
 | 
			
		||||
 *   This code is distributed in the hope that it will be useful, but      *
 | 
			
		||||
 *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
 | 
			
		||||
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
 | 
			
		||||
 *   General Public License for more details.                              *
 | 
			
		||||
 *                                                                         *
 | 
			
		||||
 *   A copy of the GNU General Public License is available on the World    *
 | 
			
		||||
 *   Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also      *
 | 
			
		||||
 *   obtain it by writing to the Free Software Foundation,                 *
 | 
			
		||||
 *   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.        *
 | 
			
		||||
 *                                                                         *
 | 
			
		||||
 ***************************************************************************
 | 
			
		||||
 | 
			
		||||
  Abstract:
 | 
			
		||||
    Demo to show, how a Thread waits for another.
 | 
			
		||||
}
 | 
			
		||||
unit WaitForUnit1;
 | 
			
		||||
 | 
			
		||||
{$mode objfpc}{$H+}
 | 
			
		||||
 | 
			
		||||
interface
 | 
			
		||||
 | 
			
		||||
uses
 | 
			
		||||
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, Buttons,
 | 
			
		||||
  StdCtrls, LCLProc;
 | 
			
		||||
 | 
			
		||||
type
 | 
			
		||||
 | 
			
		||||
  { TBaseThread }
 | 
			
		||||
 | 
			
		||||
  TBaseThread = class(TThread)
 | 
			
		||||
  public
 | 
			
		||||
    procedure Log(const Msg: string; AppendLineEnd: boolean = true);
 | 
			
		||||
  end;
 | 
			
		||||
 | 
			
		||||
  { TThreadA }
 | 
			
		||||
 | 
			
		||||
  TThreadA = class(TBaseThread)
 | 
			
		||||
  public
 | 
			
		||||
    WaitForB: PRtlEvent;
 | 
			
		||||
    procedure Execute; override;
 | 
			
		||||
  end;
 | 
			
		||||
 | 
			
		||||
  { TThreadB }
 | 
			
		||||
 | 
			
		||||
  TThreadB = class(TBaseThread)
 | 
			
		||||
  private
 | 
			
		||||
    FCounter: integer;
 | 
			
		||||
  public
 | 
			
		||||
    procedure Execute; override;
 | 
			
		||||
    property Counter: integer read FCounter write FCounter;
 | 
			
		||||
  end;
 | 
			
		||||
 | 
			
		||||
  { TForm1 }
 | 
			
		||||
 | 
			
		||||
  TForm1 = class(TForm)
 | 
			
		||||
    Button1: TButton;
 | 
			
		||||
    Memo1: TMemo;
 | 
			
		||||
    procedure Button1Click(Sender: TObject);
 | 
			
		||||
    procedure FormCreate(Sender: TObject);
 | 
			
		||||
    procedure FormDestroy(Sender: TObject);
 | 
			
		||||
  private
 | 
			
		||||
    ACriticalSection: TRTLCriticalSection;
 | 
			
		||||
    MsgText: string;
 | 
			
		||||
    procedure AddMessage;
 | 
			
		||||
  public
 | 
			
		||||
    ThreadA: TThreadA;
 | 
			
		||||
    ThreadB: TThreadB;
 | 
			
		||||
  end;
 | 
			
		||||
 | 
			
		||||
var
 | 
			
		||||
  Form1: TForm1; 
 | 
			
		||||
 | 
			
		||||
implementation
 | 
			
		||||
 | 
			
		||||
{ TForm1 }
 | 
			
		||||
 | 
			
		||||
procedure TForm1.Button1Click(Sender: TObject);
 | 
			
		||||
begin
 | 
			
		||||
  if ThreadA=nil then
 | 
			
		||||
    ThreadA:=TThreadA.Create(false);
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
procedure TForm1.FormCreate(Sender: TObject);
 | 
			
		||||
begin
 | 
			
		||||
  InitCriticalSection(ACriticalSection);
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
procedure TForm1.FormDestroy(Sender: TObject);
 | 
			
		||||
begin
 | 
			
		||||
  DoneCriticalsection(ACriticalSection);
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
procedure TForm1.AddMessage;
 | 
			
		||||
begin
 | 
			
		||||
  Memo1.Lines.Text:=MsgText;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
{ TThreadA }
 | 
			
		||||
 | 
			
		||||
procedure TThreadA.Execute;
 | 
			
		||||
begin
 | 
			
		||||
  Form1.ThreadB:=TThreadB.Create(false);
 | 
			
		||||
  // create event
 | 
			
		||||
  WaitForB:=RTLEventCreate;
 | 
			
		||||
  while not Application.Terminated do begin
 | 
			
		||||
    Log('A: wait for B ...');
 | 
			
		||||
    // wait infinitely (until B wakes A)
 | 
			
		||||
    RtlEventWaitFor(WaitForB);
 | 
			
		||||
    Log('A: ThreadB.Counter='+IntToStr(Form1.ThreadB.Counter));
 | 
			
		||||
  end;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
{ TThreadB }
 | 
			
		||||
 | 
			
		||||
procedure TThreadB.Execute;
 | 
			
		||||
var
 | 
			
		||||
  i: Integer;
 | 
			
		||||
begin
 | 
			
		||||
  Counter:=0;
 | 
			
		||||
  while not Application.Terminated do begin
 | 
			
		||||
    Log('B: Working ...');
 | 
			
		||||
    for i:=1 to 5 do begin
 | 
			
		||||
      Sleep(300);
 | 
			
		||||
      Log('.....  ',false);
 | 
			
		||||
    end;
 | 
			
		||||
    Log('');
 | 
			
		||||
    inc(Counter);
 | 
			
		||||
    Log('B: Wake A');
 | 
			
		||||
    // wake A
 | 
			
		||||
    RtlEventSetEvent(Form1.ThreadA.WaitForB);
 | 
			
		||||
  end;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
{ TBaseThread }
 | 
			
		||||
 | 
			
		||||
procedure TBaseThread.Log(const Msg: string; AppendLineEnd: boolean);
 | 
			
		||||
var
 | 
			
		||||
  s: String;
 | 
			
		||||
begin
 | 
			
		||||
  EnterCriticalsection(Form1.ACriticalSection);
 | 
			
		||||
  s:=Msg;
 | 
			
		||||
  if AppendLineEnd then
 | 
			
		||||
    s:=s+LineEnding;
 | 
			
		||||
  dbgout(s);
 | 
			
		||||
  Form1.MsgText:=Form1.MsgText+s;
 | 
			
		||||
  Synchronize(@Form1.AddMessage);
 | 
			
		||||
  LeaveCriticalsection(Form1.ACriticalSection);
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
initialization
 | 
			
		||||
  {$I waitforunit1.lrs}
 | 
			
		||||
 | 
			
		||||
end.
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user