AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

TParallel for: wie Schleife abbrechen?

Ein Thema von Harry Stahl · begonnen am 21. Nov 2014 · letzter Beitrag vom 22. Nov 2014
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.534 Beiträge
 
Delphi 11 Alexandria
 
#1

TParallel for: wie Schleife abbrechen?

  Alt 21. Nov 2014, 22:56
Leider sind die Informationen zur TParallel-Library noch sehr spärlich.

Wie kann man eine TParallel.for schleife eigentlich vorzeitig abbrechen?
Also abbrechen, bevor alle Iterationen durchlaufen sind?

Ein "break" scheint es nicht zu geben.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: TParallel for: wie Schleife abbrechen?

  Alt 21. Nov 2014, 23:09
Du musst dir ein zentrales Break selber bauen ...
Delphi-Quellcode:
procedure Foo;
var
  LBreak: Boolean;
  LValue: Integer;
begin
  LBreak := False;
  LValue := 0;
  TParallel.&For( 1, 1000,
      procedure( L: Integer )
    begin
      if not LBreak
      then
        begin
          Inc( LValue );
          LBreak := L = 100;
        end;
    end );
  Writeln( LValue );
end;
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (21. Nov 2014 um 23:13 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.534 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: TParallel for: wie Schleife abbrechen?

  Alt 21. Nov 2014, 23:27
OK, das geht, aber offensichtlich wird die For Schleife dann trotzdem die vorgesehene Anzahl durchlaufen, nur, dass eben nichts abgearbeitet wird.

Gibt es da wirklich nichts anderes?

Mal Frage am Rande: Warum verwendest Du immer "Tparallel.&For", statt "TParallel.For"?

In der Hilfe steht es auch mit "&", warum eigentlich?
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: TParallel for: wie Schleife abbrechen?

  Alt 21. Nov 2014, 23:30
Ja, da gibt es doch ein Break (mir war doch auch so )
Delphi-Quellcode:
procedure Foo;
var
  LValue: Integer;
begin
  LValue := 0;
  TParallel.&For( 1, 1000,
      procedure( L: Integer; S: TParallel.TLoopState )
    begin
      if not S.ShouldExit
      then
        begin
          Inc( LValue );
          if L = 500
          then
            S.Break;
        end;
    end );
  Writeln( LValue );
end;
Da wird auf jeden Fall früher abgebrochen, allerdings laufen ein paar Tasks noch durch die Schleife. Sieht man schön, wenn man das ausführt
Delphi-Quellcode:
procedure Foo;
var
  LValue: Integer;
begin
  LValue := 0;
  TParallel.&For( 1, 1000,
      procedure( L: Integer; S: TParallel.TLoopState )
    begin
// if not S.ShouldExit
// then
// begin
          Inc( LValue );
          if L = 500
          then
            S.Break;
// end;
    end );
  Writeln( LValue );
end;
Bei mir kommt dann regelmäßig 529 heraus.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: TParallel for: wie Schleife abbrechen?

  Alt 21. Nov 2014, 23:33
Mal Frage am Rande: Warum verwendest Du immer "Tparallel.&For", statt "TParallel.For"?

In der Hilfe steht es auch mit "&", warum eigentlich?
Weil for ein reserviertes Wort ist. Und um das so zu deklarieren muss man ein & davor setzen.
Delphi-Quellcode:
TFoo = class
  procedure &For;
  procedure &Type;
  procedure &Begin;
  procedure &End;
  procedure &Class;
  procedure &procedure;
end;
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.534 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: TParallel for: wie Schleife abbrechen?

  Alt 21. Nov 2014, 23:41
Super, so was hatte ich gesucht, aber leider nicht gefunden.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

AW: TParallel for: wie Schleife abbrechen?

  Alt 21. Nov 2014, 23:50
Super, so was hatte ich gesucht, aber leider nicht gefunden.
Steht aber in der Doku http://docwiki.embarcadero.com/Libra....TParallel.For
Delphi-Quellcode:
class function &For(Sender: TObject; ALowInclusive, AHighInclusive: Integer; AIteratorEvent: TIteratorEvent): TLoopResult; overload; static; inline;
class function &For(Sender: TObject; ALowInclusive, AHighInclusive: Integer; AIteratorEvent: TIteratorEvent; APool: TThreadPool): TLoopResult; overload; static; inline;
class function &For(Sender: TObject; ALowInclusive, AHighInclusive: Integer; AIteratorEvent: TIteratorStateEvent): TLoopResult; overload; static; inline;
class function &For(Sender: TObject; ALowInclusive, AHighInclusive: Integer; AIteratorEvent: TIteratorStateEvent; APool: TThreadPool): TLoopResult; overload; static; inline;
class function &For(Sender: TObject; AStride, ALowInclusive, AHighInclusive: Integer; AIteratorEvent: TIteratorEvent): TLoopResult; overload; static; inline;
class function &For(Sender: TObject; AStride, ALowInclusive, AHighInclusive: Integer; AIteratorEvent: TIteratorEvent; APool: TThreadPool): TLoopResult; overload; static; inline;
class function &For(Sender: TObject; AStride, ALowInclusive, AHighInclusive: Integer; AIteratorEvent: TIteratorStateEvent): TLoopResult; overload; static; inline;
class function &For(Sender: TObject; AStride, ALowInclusive, AHighInclusive: Integer; AIteratorEvent: TIteratorStateEvent; APool: TThreadPool): TLoopResult; overload; static; inline;
class function &For(ALowInclusive, AHighInclusive: Integer; const AIteratorEvent: TProc<Integer>): TLoopResult; overload; static; inline;
class function &For(ALowInclusive, AHighInclusive: Integer; const AIteratorEvent: TProc<Integer>; APool: TThreadPool): TLoopResult; overload; static; inline;
{ da } class function &For(ALowInclusive, AHighInclusive: Integer; const AIteratorEvent: TProc<Integer, TLoopState>): TLoopResult; overload; static; inline;
{ da } class function &For(ALowInclusive, AHighInclusive: Integer; const AIteratorEvent: TProc<Integer, TLoopState>; APool: TThreadPool): TLoopResult; overload; static; inline;
class function &For(AStride, ALowInclusive, AHighInclusive: Integer; const AIteratorEvent: TProc<Integer>): TLoopResult; overload; static; inline;
class function &For(AStride, ALowInclusive, AHighInclusive: Integer; const AIteratorEvent: TProc<Integer>; APool: TThreadPool): TLoopResult; overload; static; inline;
{ da } class function &For(AStride, ALowInclusive, AHighInclusive: Integer; const AIteratorEvent: TProc<Integer, TLoopState>): TLoopResult; overload; static; inline;
{ da } class function &For(AStride, ALowInclusive, AHighInclusive: Integer; const AIteratorEvent: TProc<Integer, TLoopState>; APool: TThreadPool): TLoopResult; overload; static; inline;
class function &For(Sender: TObject; ALowInclusive, AHighInclusive: Int64; AIteratorEvent: TIteratorEvent64): TLoopResult; overload; static; inline;
class function &For(Sender: TObject; ALowInclusive, AHighInclusive: Int64; AIteratorEvent: TIteratorEvent64; APool: TThreadPool): TLoopResult; overload; static; inline;
class function &For(Sender: TObject; ALowInclusive, AHighInclusive: Int64; AIteratorEvent: TIteratorStateEvent64): TLoopResult; overload; static; inline;
class function &For(Sender: TObject; ALowInclusive, AHighInclusive: Int64; AIteratorEvent: TIteratorStateEvent64; APool: TThreadPool): TLoopResult; overload; static; inline;
class function &For(Sender: TObject; AStride, ALowInclusive, AHighInclusive: Int64; AIteratorEvent: TIteratorEvent64): TLoopResult; overload; static; inline;
class function &For(Sender: TObject; AStride, ALowInclusive, AHighInclusive: Int64; AIteratorEvent: TIteratorEvent64; APool: TThreadPool): TLoopResult; overload; static; inline;
class function &For(Sender: TObject; AStride, ALowInclusive, AHighInclusive: Int64; AIteratorEvent: TIteratorStateEvent64): TLoopResult; overload; static; inline;
class function &For(Sender: TObject; AStride, ALowInclusive, AHighInclusive: Int64; AIteratorEvent: TIteratorStateEvent64; APool: TThreadPool): TLoopResult; overload; static; inline;
class function &For(ALowInclusive, AHighInclusive: Int64; const AIteratorEvent: TProc<Int64>): TLoopResult; overload; static; inline;
class function &For(ALowInclusive, AHighInclusive: Int64; const AIteratorEvent: TProc<Int64>; APool: TThreadPool): TLoopResult; overload; static; inline;
{ da } class function &For(ALowInclusive, AHighInclusive: Int64; const AIteratorEvent: TProc<Int64, TLoopState>): TLoopResult; overload; static; inline;
{ da } class function &For(ALowInclusive, AHighInclusive: Int64; const AIteratorEvent: TProc<Int64, TLoopState>; APool: TThreadPool): TLoopResult; overload; static; inline;
class function &For(AStride, ALowInclusive, AHighInclusive: Int64; const AIteratorEvent: TProc<Int64>): TLoopResult; overload; static; inline;
class function &For(AStride, ALowInclusive, AHighInclusive: Int64; const AIteratorEvent: TProc<Int64>; APool: TThreadPool): TLoopResult; overload; static; inline;
{ da } class function &For(AStride, ALowInclusive, AHighInclusive: Int64; const AIteratorEvent: TProc<Int64, TLoopState>): TLoopResult; overload; static; inline;
{ da } class function &For(AStride, ALowInclusive, AHighInclusive: Int64; const AIteratorEvent: TProc<Int64, TLoopState>; APool: TThreadPool): TLoopResult; overload; static; inline;
Und wenn ich nicht weiß, was TLoopState oder TLoopResult ist, und die Doku nicht weiterweiß, dann einfach ein STRG-Klick auf das Unbekannte und direkt im Quelltest nachschauen

BTW: TIteratorStateEvent /TIteratorStateEvent64 haben auch noch den TLoopState
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (21. Nov 2014 um 23:53 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.534 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: TParallel for: wie Schleife abbrechen?

  Alt 22. Nov 2014, 00:00
Ich muss gestehen, das hatte ich gesehen, aber das Gewünschte nicht gefunden (ist ja auch ein wenig unübersichtlich...).

Was soll eigentlich s.shouldexit bewirken? Wenn man das aufruft, hat das anscheinend keine Auswirkungen?

In System.Threading gibt es das da:

Delphi-Quellcode:
class function TParallel.ForWorker...

 while (I < ToExclusive) and ((SharedFlags.LoopStateFlags = []) or not SharedFlags.ShouldExit) do
EDIT: Oh, jetzt gesehen, dass Shoudexit einen Wert zurückgibt, nicht setzt. Wäre aber gut, wenn man die Rückgabe von SharedFlags.ShouldExit mit True hinkriegen könnte, dann wir die While-Schleife unterbrochen

Geändert von Harry Stahl (22. Nov 2014 um 00:07 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#9

AW: TParallel for: wie Schleife abbrechen?

  Alt 22. Nov 2014, 00:10
Öhm, das ist doch offensichtlich und darum habe ich den Code doch auch in 2 Variationen eingestellt. Einmal mit Abfrage s.ShouldExit und einmal ohne. Bei beiden wird die Verarbeitung der Tasks vorzeitig abgebrochen, allerdings sind einige Tasks schon über dem PointOfNoReturn und werden trotzdem noch durch die Worker-Threads verarbeitet.

Und genau für diese durchgerutschten Tasks frage ich den LoopStateTLoopState ab. Und wenn man vorher ein TLoopState.Break aufgerufen hat, dann liefert TLoopState.ShouldExit ganz lapidar ein True .

Genau das wollen wir doch haben ... oder nicht?
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#10

AW: TParallel for: wie Schleife abbrechen?

  Alt 22. Nov 2014, 00:14
Man hätte es aber auch einfacher implementieren können, indem man z.B. auch auf Delphi-Referenz durchsuchenAbort reagiert und dann die anderen Schleifen-Threads abbricht (Break-State setzt).

Aber wenn man in dem For-Event etwas längeres macht, oder eine Schleife, dann sollte man da natürlich auch den State prüfen.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu (22. Nov 2014 um 00:17 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:53 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz