Thema: Delphi Multithreading

Einzelnen Beitrag anzeigen

Gruber_Hans_12345

Registriert seit: 14. Aug 2004
1.426 Beiträge
 
Delphi 2007 Professional
 
#1

Multithreading

  Alt 24. Jul 2023, 12:35
Hallo kann mal wer einen Blick auf meinen Code werfen - irgendwo habe ich da einen Denkfehler.

Das ist meine Threadklasse
Delphi-Quellcode:
type
    TTestThread = class(TThread)
    protected
        fWaitFinish : THandle;
        fResumeEvent : THandle;
        procedure Execute; override;
    public
        constructor Create();
        destructor Destroy; override;
    end;

destructor TTestThread.Destroy;
begin
    CloseHandle(fWaitFinish);
    CloseHandle(fResumeEvent);
    inherited;
end;

constructor TTestThread.Create();
var
    i : integer;
begin
    fResumeEvent := 0;
    fWaitFinish := CreateEvent(nil, TRUE, FALSE, nil);
    FreeOnTerminate := FALSE;
    inherited Create(TRUE);
end;

procedure TTestThread.Execute;

    procedure internalExecute;
    var
        i : integer;
        x : Byte;
    begin
        x := 9;
        for i:=1 to 10000000 do begin
            x := x xor (Random(9999999) mod 255);
        end;
        SetEvent(fWaitFinish);
    end;

begin
    fResumeEvent := CreateEvent(nil, TRUE, FALSE, nil);
    repeat
        internalExecute;
        if Terminated then break;
        WaitForSingleObject(fResumeEvent, INFINITE);
        ResetEvent(fResumeEvent);
    until Terminated;
    SetEvent(fWaitFinish);
end;
Und so rufe ich das mit einer Art Threadpool auf

Delphi-Quellcode:
procedure TfrMDIChild.Button19Click(Sender: TObject);
var
    maxThreads : integer;
    tempFunc : TInterpreterFunDesc;
    hArrWait : array of THandle;
    threadList : array of TTestThread;

    function GetIdleThread : integer;
    var
        i : integer;
    begin
        for i:=0 to maxThreads-1 do
            if hArrWait[i] = 0 then begin
                threadList[i] := TTestThread.Create();
                hArrWait[i] := threadList[i].fWaitFinish;
                Result := i;
                exit;
            end;
        repeat
            Result := WaitForMultipleObjects(length(hArrWait), @hArrWait[0], FALSE, INFINITE);
        until (Result >= 0) and (Result < maxThreads);
        Result := Result - WAIT_OBJECT_0;
    end;

    procedure InitThreads;
    var
        i : integer;
    begin
        setlength(threadList, maxThreads);
        setlength(hArrWait, maxThreads);
        for i:=0 to maxThreads-1 do
            hArrWait[i] := 0;
    end;
    
var
    i : integer;
    threadIdx : integer;
    perfFreq : int64;
    perfStart : int64;
    perfEnd : int64;
begin
    QueryPerformanceFrequency(perfFreq);

    QueryPerformanceCounter(perfStart);
    maxThreads := TButton(Sender).Tag;
    InitThreads;
    for i:=0 to 100 do begin
        threadIdx := GetIdleThread;
        if threadList[threadIdx].fResumeEvent = 0 then begin
            threadList[threadIdx].Resume;
        end
        else begin
            ResetEvent(threadList[threadIdx].fWaitFinish);
            SetEvent(threadList[threadIdx].fResumeEvent);
        end;
    end;
    QueryPerformanceCounter(perfEnd);

    setlength(threadList, 0);
    setlength(hArrWait, 0);
    QueryPerformanceCounter(perfEnd);
    Memo1.Lines.Add('Threading ('+IntToStr(maxThreads)+' Threads : '+FormatFloat('0.00', (perfEnd-perfStart) * 1000 / perfFreq)+' ms');
end;
Den Testbutton rufe ich einmal mit einem Thread auf und einmal das er acht Threads machen soll
Das Ergebnis ist dann
Code:
Threading (1 Threads : 4446,57 ms
Threading (8 Threads : 5980,15 ms
Was übersehe ich da das er bei 8 gleichzeitigen Threads die Dauer so lange ist? (Die CPU Auslastung geht aber da schön auf fast 100% hoch)
Gruss Hans

2B or not 2B, that is FF
  Mit Zitat antworten Zitat