Announcement

Collapse
No announcement yet.

Threads und 100% Systemlast

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Threads und 100% Systemlast

    Moin!<BR>
    Ich habe mal angefangen mit Threads zu programmieren.<BR>
    Mein erster Test war ein Programm, in dem 6 Progressbars gleichzeigt hochgezählt wurden. - Klappte auch soweit auch ganz gut.<BR>
    Als zweite Übung wollte ich eine Art 'Portscanner' basteln. Also: Tclientsocket.port=x+1; .open; ... Bei keiner Exception merken, etc.<BR>
    Da das open ja länger dauert (da Timeout), dachte ich, ich mache einfach viele Threads, so das die ganze Arbeit schneller geht. Es dürfte ja kein Problem sein, wenn so hundert Threads auf die Fehlermeldung warten.<BR>
    Nur: Unter Delphi klappt das bis ca. 150 Threads, danach, geht das System in die Knie. Ohne Delphi (direkt gestartet) mach das System schon bei 50 Threads schlapp.<BR>
    Das sieht so aus: Im Taskmanager zeigt der plötzlich 100% Systemlast (Delphi-Test 100 Threads war max. 75% Last), ca. 90% Kernel-Zeit, das Formular baut sich nicht mehr auf, und das System ist mehr als träge.<BR>
    Hier mein Code: (Sorry, für die sparsame Kommentierung, sollte 'nur' eine Übung sein).<BR>
    <PRE>
    unit main;

    interface

    uses
    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
    StdCtrls, ScktComp, ComCtrls;

    type
    TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    ListBox1: TListBox;
    ProgressBar1: TProgressBar;
    Label1: TLabel;
    Button2: TButton;
    ListBox2: TListBox;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    private
    { Private-Deklarationen }
    public
    { Public-Deklarationen }
    abbruch:boolean;
    end;

    tp=procedure;
    tf=function:boolean;

    Tmytread=class(TTHread)
    private
    tcs:TClientsocket;
    tl:TListBox;
    von,bis,akt:integer;
    eip:string;
    proc:tp;
    abbruch:boolean;
    ab:tf;
    protected
    procedure Execute; override;
    procedure hinzu;
    procedure abf;
    public
    constructor create(lb:TListBox;zaehl:tp; abbr:tf; ip: string; v, b: integer);
    destructor destroy; override;
    end;

    var
    Form1: TForm1;

    implementation

    {$R *.DFM}

    { Tmytread }

    procedure Tmytread.abf;
    begin
    proc;
    abbruch:=ab;
    end;

    constructor Tmytread.create(lb:TListBox; zaehl:tp; abbr:tf; ip: string; v, b: integer);
    begin
    inherited create(True);
    von:=v;
    bis:=b;
    akt:=v;
    tl:=lb;
    eip:=ip;
    proc:=zaehl;
    ab:=abbr;
    tcs:=TClientSocket.Create(NIL);
    tcs.Address:=eip;
    tcs.ClientType:=ctBlocking;
    FreeOnTerminate:=True;
    end;

    destructor Tmytread.destroy;
    begin
    tcs.free;
    tcs:=NIL;
    inherited;
    end;

    procedure Tmytread.Execute;
    begin
    akt:=von;
    while (akt<=bis) and (not abbruch) do begin
    tcs.Port:=akt;
    try
    tcs.Open;
    Synchronize(hinzu);
    except
    end;
    tcs.close;
    inc(akt);
    Synchronize(abf);
    end;
    end;

    procedure Tmytread.hinzu;
    begin
    tl.Items.Add(IntToStr(akt)+' OK')
    end;

    procedure zaehl;
    var x:integer;
    begin
    x:=Form1.ProgressBar1.Position+1;
    Form1.ProgressBar1.Position:=x;
    Form1.Label1.Caption:=IntToStr(x);
    Application.ProcessMessages;
    end;

    function abbr:boolean;
    begin
    result:=form1.abbruch;
    end;
    </PRE>
    ...to be continued...

  • #2
    <PRE>
    procedure TForm1.Button1Click(Sender: TObject);
    var pro,akt,y,x:integer;
    tmt:Tmytread;
    const anz=200;
    max=65535;
    begin
    abbruch:=False;
    pro:=max div anz;
    akt:=1;
    for x:=1 to anz-1 do begin
    y:=akt+pro;
    tmt:=Tmytread.create(ListBox1,zaehl,abbr,Edit1.Tex t,akt,y);
    ListBox2.Items.add(inttostr(akt)+' - '+inttostr(y));
    akt:=y+1;
    tmt.Resume;
    sleep(1);
    end;
    if akt<max then
    Tmytread.create(ListBox1,zaehl,abbr,Edit1.Text,akt ,max);
    ProgressBar1.max:=max;
    ProgressBar1.Position:=0;
    end;

    procedure TForm1.FormCreate(Sender: TObject);
    begin
    ProgressBar1.max:=65535;
    end;

    procedure TForm1.Button2Click(Sender: TObject);
    begin
    abbruch:=True;
    end;

    end.
    </PRE>
    System: NT5(W2K); 900Celeron/256MB. Delphi5 Ent.<BR>
    Hoffe Ihr seht was.<BR>
    THX und<BR>
    MFG,cu,LLAP Ralph Erd

    Comment


    • #3
      Hallo,

      &gt; ...100% Systemlast .., ca. 90% Kernel-Zeit, das Formular baut sich nicht mehr auf...

      das hört sich nach einem der TMultiReadExclusiveWriteSynchronizer-Bugs an, die seit Delphi 5 tief in der VCL schlummern (1 Bug sorgt für einen Deadlock und 2 Bugs für eine Endlosschleife). Die Suche nach der Zeichenkette <i>TMultiReadExclusiveWriteSynchronizer</i> sollte einige Hinweise und ein inoffizielles Patch liefern

      Comment


      • #4
        Moin!<BR>
        Danke. Gefunden. nur:<BR>
        Das Ding ist für D6. Wir haben aber D5. Ich habe daraufhin probiert, nach der Anleitung die Sysutils abzuändern.<BR>
        Ich bin aber sofort gegen die Wand gelaufen: Der will die FFMT.OBJ haben. Die haben wir aber nicht, nur die FFMT.ASM.<BR>
        Brauchen wir jetzt einen Assembler-"Compiler" oder gibt es noch eine Möglichkeit die ASM zu OBJ umzuwandeln?<BR>
        MFG,cu,LLAP Ralph Erd

        Comment


        • #5
          Hallo,

          &gt;Die haben wir aber nicht, nur die FFMT.ASM.

          dieses Teil gibt es in Delphi 6 nicht mehr, daher funktioniert die Beschreibung dort. Wenn beim Compilieren von SysUtils.pas der Compiler an der Zeile <i>{$L FFMT.OBJ}</i> stehen bleibt, kann man den Weg probieren, den Borland empfielt:

          Frage: "<i>When recompiled under D5 an old D3 project that used sysutils broke on the line: {$L FFMT.OBJ} there is no file on my machine with that name. Is there a compiler setting or did I miss an installation step?"</i>

          Antwort: "<i>You're trying to recompile the Delphi RTL, which means you have the
          Source\RTL\Sys directory in your project search path. If you really need to recompile the Delphi RTL use the MAKEFILE under \Source\RTL.</i>".

          Was passiert beim Aufruf des Makefiles

          Comment


          • #6
            Moin!<BR>
            <PRE>
            C:\fp\dp\Delphi5\Source\Rtl>C:\fp\dp\Delphi5\Bin\m ake
            MAKE Version 5.2 Copyright (c) 1987, 1998 Inprise Corp.
            tasm32 -zn -m3 -t -w- -zn -isys sys\assign,sys\assign.obj
            Der Befehl "tasm32" ist entweder falsch geschrieben oder
            konnte nicht gefunden werden.

            ** error 1 ** deleting sys\assign.obj
            </PRE>
            Wir haben leider kein TASM <BR>
            Gibts irgend ne Uraltversion zum freiem Download?<BR>
            Danke,<BR>
            MFG,cu,LLAP Ralph Erd

            Comment

            Working...
            X