Konsolen-Programm mit Thread(s) - unit crt nicht verwendbar?

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Bitschubser
Beiträge: 61
Registriert: Mo 27. Aug 2012, 15:43

Konsolen-Programm mit Thread(s) - unit crt nicht verwendbar?

Beitrag von Bitschubser »

Hallo zusammen,

als Fingerübung hab ich mir mal die Programmierung mit threads angesehen - Plattform Windows.
Tutorial http://wiki.freepascal.org/Multithreade ... utorial/de gelesen, und spätestens seit http://www.lazarusforum.de/viewtopic.php?f=10&t=5372 ist mir auch klar, warum mein thread beim ersten synchronize(...) hängen blieb.

Aber: Was auch nicht funktioniert ist die Benutzung der unit crt.
Sobald ich crt benutze werden im Konsolenfenster nur noch Leerzeichen ausgegeben!
Ich hab gedacht ich könnte mal in crt reingucken um zu sehen was schiefläuft, aber irgendwie funtionieren Breaktpoints in crt grundsätzlich nicht (nicht mal im "Hautpprogramm"/Initialization-Abschnitt) - mach ich da was grundsätzlich falsch?
Beispielprogramm s.u., entspricht weitestgehend dem Beispiel aus dem Tutorial, nur halt ohne GUI.
Achso, nur am Rande - mir ist klar, dass StatusText korrumpiert werden könnte.
NACHTRAG: Unter Linux tritt das Problem nicht auf.

Gruß, Ingo

Code: Alles auswählen

program project1;
 
{$mode objfpc}{$H+}
 
uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes, SysUtils, CustApp, Crt,
 
  Unit1;
 
type
 
  TMyApplication = class(TCustomApplication)
  protected
    procedure DoRun; override;
  public
    constructor Create(TheOwner: TComponent); override;
    destructor Destroy; override;
  end;
 
procedure TMyApplication.DoRun;
var
  ErrorMsg: String;
  oldTime, newTime : TDateTime;
  MyThread : TMyThread;
 
begin
 
  MyThread := TMyThread.Create(false);
 
  oldTime := Now;
 
  repeat
 
    newTime := Now;
    if newTime >= oldTime + 1/24/3600 then begin
      Write(#13, DateTimeToStr(newTime), ' ', MyThread.StatusText, '    ');
      oldTime := newTime;
    end else Sleep(1000 - Round((newTime - oldTime) * 24*3600*1000));
  until false; //keypressed;
  Terminate;
end;
 
constructor TMyApplication.Create(TheOwner: TComponent);
begin
  inherited Create(TheOwner);
  StopOnException:=True;
end;
 
destructor TMyApplication.Destroy;
begin
  inherited Destroy;
end;
 
var
  Application: TMyApplication;
begin
  Application:=TMyApplication.Create(nil);
  Application.Title:='My Application';
  Application.Run;
  Application.Free;
end.                            

Code: Alles auswählen

unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils;
 
Type
    TShowStatusEvent = procedure(Status: String) of Object;
 
    TMyThread = class(TThread)
    private
    protected
      procedure Execute; override;
    public
      StatusText : string;
      Constructor Create(CreateSuspended : boolean);
    end;
 
implementation
 
  constructor TMyThread.Create(CreateSuspended : boolean);
  begin
    FreeOnTerminate := True;
    inherited Create(CreateSuspended);
  end;
 
  procedure TMyThread.Execute;
 
  var
    i : longint;
 
  begin
    while not Terminated do begin
      Inc(i);
      if i MOD 100000000 = 0 then
        StatusText := ' Counted to ' + IntToStr(i) + '!';
    end;
  end;
 
end.


Bitschubser
Beiträge: 61
Registriert: Mo 27. Aug 2012, 15:43

Re: Konsolen-Programm mit Thread(s) - unit crt nicht verwend

Beitrag von Bitschubser »

Also unter "nicht thread-safe" verstehe ich, dass eine Routine nicht von mehreren Threads eines Porgramms gleichzeitig benutzt werden kann, oder auch einfach dass eine Routine nicht reentrant ist. Ich hab's extra noch mal nachgelesen, und zumindest Wikipedia ist meiner Meinung.
Solange ich die unit crt aber nur in meinem Hauptthread (oder einfach nur genau einem thread meines Programmes) benutze sehe ich da keine Einschränkung, sonst dürfte ich ja auch noch ganz andere Sachen nicht machen, nur weil mein Programm threads hat.
Egal, was mich mittlerweile viel mehr interessiert:
Warum funktionieren Breakpoints ich in der unit crt nicht? (Crt wird offensichtlich auch gar nicht neu kompiliert wenn ich sie ändere, selbst wenn ich crt.pp lösche wird es neu erzeugt ohne crt.pas zu kompilieren. Wenn ich crt.pas über Start->Datei neu kompilieren kompiliere funktionieren die includes nicht - da fehlt ein ..\inc\ vor den Dateinamen - warum?)

Benutzeravatar
theo
Beiträge: 10900
Registriert: Mo 11. Sep 2006, 19:01

Re: Konsolen-Programm mit Thread(s) - unit crt nicht verwend

Beitrag von theo »

Weil Unit Crt nicht zu deinem Projekt gehört. Sie gehört noch nicht einmal zur LCL (Lazarus) sondern zur RTL (FPC).
Diese sind standardmässig nicht mit Debug Info kompiliert.

Du findest weitere infos in Netz, z.B.

http://www.lazarusforum.de/viewtopic.php?f=5&t=3919
http://free-pascal-general.1045716.n5.n ... 21010.html
Zuletzt geändert von theo am Di 10. Dez 2013, 14:16, insgesamt 1-mal geändert.

Bitschubser
Beiträge: 61
Registriert: Mo 27. Aug 2012, 15:43

Re: Konsolen-Programm mit Thread(s) - unit crt nicht verwend

Beitrag von Bitschubser »

theo hat geschrieben:Weil Unit Crt nicht zu deinem Programms gehört. Sie gehört noch nicht einmal zur LCL (Lazarus) sondern zur RTL (FPC).
Diese sind standardmässig nicht mit Debug Info kompiliert.
Das erklärt natürlich einiges.
Du findest weitere infos in Netz, z.B.
Naja, ich nicht, daher ja die Frage. Rückblickend hab ich natürlich völlig falsch gesucht - schon weil ich gar nicht an Lazarus vs. fpc gedacht habe.
Danke für die links, ich hab's für später abgelegt, weil unter Linux (wo ich's eigentlich benutzen wollte) geht die crt ja trotz threading...

Antworten