AGB  ·  Datenschutz  ·  Impressum  







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

Mal wieder Threads

Ein Thema von DelTurbo · begonnen am 5. Nov 2011 · letzter Beitrag vom 6. Nov 2011
Antwort Antwort
Seite 1 von 2  1 2      
Medium

Registriert seit: 23. Jan 2008
3.689 Beiträge
 
Delphi 2007 Enterprise
 
#1

AW: Mal wieder Threads

  Alt 5. Nov 2011, 12:34
Wie versendest du denn Strings mit PostMessage?
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#2

AW: Mal wieder Threads

  Alt 5. Nov 2011, 12:36
Sollte kein Problem sein, da ja alles im selben Prozess bleibt.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.689 Beiträge
 
Delphi 2007 Enterprise
 
#3

AW: Mal wieder Threads

  Alt 5. Nov 2011, 12:38
Wenn es ein Pointer auf einen lokalen String ist, wird's potenziell ekelig.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
DelTurbo

Registriert seit: 12. Dez 2009
Ort: Eifel
1.248 Beiträge
 
Delphi 2007 Architect
 
#4

AW: Mal wieder Threads

  Alt 5. Nov 2011, 12:54
Nein. Ich mache mir für sowas immer Records. Das erste ist ein InUse:Boolean. Ist der Record belegt, nehm ich den nächsten oder warte bis einer frei wird.

Da wo ich "reinposte" sieht der anfang immer so aus

Delphi-Quellcode:
procedure TReadDataFrm.RefreshRDObj(var Msg: TMessage);
var
   i      :Integer;
begin
      i := Integer(Msg.lParam);
da habe ich dann die nummer auf dem record, der "zu mir" gehört. Der Record ist Global und da stehen dann alle sachen drinne die ich in dem moment brauche. Strings,Integer usw..

Ich habe nun mal SendMessage genommen. Da der fehler nicht reproduzierbar ist, kann ich nur warten....
Alle meine Rechtschreibfehler sind Urheberrechtlich geschützt!!
  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: Mal wieder Threads

  Alt 5. Nov 2011, 13:10
Da habe ich dann die nummer auf dem record, der "zu mir" gehört. Der Record ist Global und da stehen dann alle sachen drinne die ich in dem moment brauche. Strings,Integer usw..
Hmmm, warum nimmst du keine TCollection und definierst dir ein passendes TCollectionItem dazu.
Von dem neuen TCollectionItem übergibst du per PostMessage oder SendMessage die ID (nicht den Index!) und schickst das auf die Reise. Der Empfänger kann nun aus dieser Collection sich das passende Item (mit der ID) herausnehmen und hat auch alle Informationen.

Generell würde ich auch die Jobs nicht als Thread definieren, sondern die Jobs durch einen WorkThread ausführen lassen.
Der WorkThread wird über einen WorkManager gestartet und dieser verwaltet passenderweise auch noch die Collection mit den Nachrichten.

Hier mal ein schnell hingetippeltes Projekt
Delphi-Quellcode:
type
IWorkManager = interface
procedure SendMessage(<ParameterListe anpassen>);
procedure PostMessage(<ParameterListe anpassen>);
end;

// Interface für den WorkJob
IWorkJob = interface
procedure SetWorkManager( aWorkManager : IWorkManager );
procedure DoExecute;
end;

TWorkThread = class( TThread )
private
  fWorkJob : IWorkJob;
protected
  procedure Execute; override;
public
  constructor Create( CreateSuspended : Booelan; aWorkJob : IWorkJob );
end;

TWorkManager = class( TInterfacedObject, IWorkManager )
public
  procedure AddJob( aWorkJob : IWorkJob );
end;

procedure TWorkManager.AddJob( aWorkJob : IWorkJob );
begin
  aWorkJob.SetWorkManager( Self );
  with TWorkThread.Create( True, aWorkJob ) do
  begin
    FreeOnTerminate := True;
    Resume;
  end;
end;
Es gibt auch noch diese Bei Google suchenOmniThreadLibrary die sowas schon direkt alles mitbringt (glaube ich).
Sowas baue ich aber lieber selber
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
Furtbichler
(Gast)

n/a Beiträge
 
#6

AW: Mal wieder Threads

  Alt 5. Nov 2011, 13:18
Also ich kapsle einen String in einer Klasse. Das ist bestimmt oversized, aber bisher hatte ich damit keine Probleme...
(Das hier ist allerdings aus dem Gedächtnis)
Delphi-Quellcode:
Type
  TStringContainer = Class
  Public
     MessageString : String;
     Constructor Create (aMessage : String);
  End;

Constructor TStringContainer.Create (aMessage : String);
Begin
  MessageString := aMessage
End;

...
Procedure TMyThread.SendAString (AString : String);
Begin
  PostMessage(MainHandle, WM_STRING, Integer(TSTringContainer.Create(aString)),0);
End;

...
Procedure TMainTask.ReceivStringMessageHandler (Var Msg : TMessage);
Begin
  DoSomethingWith(TStringContainer(Msg.wParam).MessageString);
  TStringContainer(Msg.wParam).Free
End;
Is das ok so?

Nachtrag: Da mir das mit der Referenzzählung bei Strings nicht geheuer ist, mache ich das so.


@Sir Rufo: Threads mit FreeOnTerminate habe ich mir abgewöhnt, denn wenn ich die Anwendung beende und der Thread noch im Speicher rumfleucht, bekomme ich jedesmal eine schöne Exception, denn der Code zum Terminieren eines Threads baut darauf auf, das die Classes.pas noch nicht ihren finalize-Teil durchlaufen hat.

Geändert von Furtbichler ( 5. Nov 2011 um 13:20 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
10.053 Beiträge
 
Delphi 12 Athens
 
#7

AW: Mal wieder Threads

  Alt 5. Nov 2011, 14:30
Delphi-Quellcode:
  with TWorkThread.Create( True, aWorkJob ) do
  begin
    FreeOnTerminate := True;
    Resume;
  end;

Ein Spiel mit dem Feuer. Mit Glück geht sowas gut, aber will man sich darauf verlassen? Nicht umsonst ist Resume mittlerweile als deprecated gekennzeichnet. Zitat aus der Hilfe:
Zitat:
Warnung: Die Methoden Resume und Suspend sollten nur für das Debuggen verwendet werden.
Hintergrund unter anderem:
Wenn der Thread zu schnell fertig ist bevor Resume beendet ist, zieht das FreeOnTerminate dem Code den Boden unter den Füßen weg. Und wenn es nur passiert, weil im Thread eine Exception auftritt, ausschließen kann man so etwas jedenfalls kaum. Dazu gibt es auch umfangreiche Diskussionen, unter anderem auch im Embarcadero Forum unter Beteiligung von deren Entwicklern. Das Fazit ist überall das gleiche: Nie Resume verwenden ist das beste.

Deshalb rate ich stattdessen dringend zu einer sauberen Lösung. Insbesondere hier im Beispiel ist das ja denkbar einfach: Einfach den Thread nicht suspended starten...
Apprun ist auch Global. Es wird alle 100ms auf 1 gesetzt, über einen normalen TTimer.
Ich frage mich die ganze Zeit wozu das ganze eigentlich global ist. Du kannst dir doch Speicher reservieren, per Message an deinen Hauptthread schicken und der gibt den wieder frei. Dann kannst du dir die ganze zusätzliche Synchronisation sparen.

Und das mit dem Timer kannst du dir dann auch sparen. Denn der Thread kann sich einfach kurz mit Sleep schlafen legen und weitermachen.

Ansonsten gibt es auch noch Events (CreateEvent, SetEvent, ...) um die Signale hin- und herzuschicken. Die sind auch threadsicher.

Mit der Variante aus dem ersten post, habe ich ein prg gemacht was bis zu 200 threads zeitgleich laufen hat.
Wobei so viele Threads das ganze natürlich sehr stark ausbremsen, wenn die wirklich zeitgleich arbeiten und nicht größtenteils schlafen.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
DelTurbo

Registriert seit: 12. Dez 2009
Ort: Eifel
1.248 Beiträge
 
Delphi 2007 Architect
 
#8

AW: Mal wieder Threads

  Alt 5. Nov 2011, 14:52
Hi,
also ich weiss nun nicht ob das mit AppRun so eine grosse rolle spielt. Ich habe es einfach in der "unit1" deklariert und fertig. Was soll ich für (theoretisch einem Byte) speicher "hohlen". Find ich bissl umständlich.

Zum Thread. Der soll nicht schlafen, der soll arbeiten. Den gedanken gang kann ich leider nicht nachvollziehen. Ich habe das nun endlich so schnell, das ich mit bis zu 150MBit (im GBitLan) den MySqlServer "anblasen" kann. Und dann soll ich ein sleep einbauen? Sorry, das verstehe ich auch nicht.

Zu den 200 Threads. Das war einmal ein Peak der erreicht wurde. Natürlich Rendern die keine Filme. Normal sind ca. 30-50 Threads, wovon bis zu 10 zeitgleich laufen können (kommt drauf an was er macht). Und selbst die, die "laufen" warten meistens nur rum bis der FTP-Server antwortet.

Danke an alle....
Alle meine Rechtschreibfehler sind Urheberrechtlich geschützt!!

Geändert von DelTurbo ( 5. Nov 2011 um 15:19 Uhr) Grund: ergänzt
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#9

AW: Mal wieder Threads

  Alt 5. Nov 2011, 18:06
Deshalb rate ich stattdessen dringend zu einer sauberen Lösung. ... Einfach den Thread nicht suspended starten...
Oder FreeOnTerminate nicht verwenden.
  Mit Zitat antworten Zitat
grl

Registriert seit: 5. Feb 2007
174 Beiträge
 
FreePascal / Lazarus
 
#10

AW: Mal wieder Threads

  Alt 5. Nov 2011, 12:55
Also, prinzipiell sollte man im Thread immer nur mit PostMessage arbeiten.

Mal so ganz ins blaue geraten: Du sendest den Text mit WM_COPYDATA - und das ist nicht Thread-geeignet.

Ein bisserl mehr Quellcode wäre nett, dann könnte man vielleicht auch eine gescheite Aussage treffen und dir leichter weiterhelfen. Mit der Kristallkugel ist's am Wochenende nix, da ist die konsequent auf Urlaub...

Gruß
Luggi
  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 04:14 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz