AGB  ·  Datenschutz  ·  Impressum  







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

Threads verwalten

Ein Thema von David Martens · begonnen am 21. Nov 2009 · letzter Beitrag vom 25. Nov 2009
Antwort Antwort
Seite 1 von 2  1 2      
David Martens

Registriert seit: 29. Sep 2003
205 Beiträge
 
Delphi XE Enterprise
 
#1

Threads verwalten

  Alt 21. Nov 2009, 01:17
Ich bin dabei ein Programm zu schreiben das verschiedene Dateien auf Änderungen überwacht. Jetzt will ich das aber in verschiedenen Threads machen. Meine Frage wie?

ein Thread soll haben:
- 1 Komponente zur Überwachung (TfisFileNotification)
- 1 Komponente zur Speicherung (Versionierung) der Änderung (TJvZlibMultiple)
- dirverse einfache Variablen wie:
Delphi-Quellcode:
    
    Name,
    WatchFolder,
    BackupFolder : string;

    IncludeFiles,
    ExcludeFiles,
    ExcludeFolder : string;
    minSize,
    maxSize : integer;
Nun weiß ich aber im Vorfeld nicht wieviele Threads ich brauche. Ich dachte da an eine TObjectList am besten eine typisierte (siehe hier).

Da ich aber noch nicht so tief in die Materie eingestiegen bin wollte ich wissen wie ich Threads in eine Liste verwalten kann.
Die Threads sind von Natur aus (vielleicht bis auf die, von mir gewünschten, Meldungen fürs Log) unabhänig. Da habe ich schon was gefunden mit PostMessage(MainForm.Handle, MY_WM_USER, SUB_MESSAGE_X, Integer(InfoRecord)); kann ich aus den einzelnen Threads die Log füllen.

Was ich jetzt noch wissen muß wie muß die Threadklasse aussehen, wie kann ich die zur Laufzeit erzeugen und wie verwalte ich die in der Liste?

Ich hoffe ich habe mich verständlich ausgedrückt und falls das alles Quatsch ist, was ich geschrieben habe dann entschuldige ich mich schonmal.

Danke
David
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#2

Re: Threads verwalten

  Alt 22. Nov 2009, 16:08
Hmm, ist ja eine sehr allgemeine Frage.

Also, ja Du kannst viele Threads erzeugen und ale einer Objectliste hinzufügen. Ob du die Liste typisieren musst, liegt an dir und der Aufgabe selbst.

Die Übergabe des Ergebnisses würde per Postmessage gehen, aber dazu muss InfoRecord extern auf dem Heap liegen, oder du verwnedest sendmessage.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
taaktaak

Registriert seit: 25. Okt 2007
Ort: Radbruch
1.993 Beiträge
 
Delphi 7 Professional
 
#3

Re: Threads verwalten

  Alt 22. Nov 2009, 16:16
PostMessage und SendMessage verwende ich auch sehr oft, darf ich da mal eine Zwischenfrage stellen:
Wie erreiche ich, dass InfoRecord auf dem Heap eingerichtet wird und damit PostMessage verwendet werden kann? Wird eine Unit-lokale Variable im Heap angelegt?
Ralph
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#4

Re: Threads verwalten

  Alt 22. Nov 2009, 16:21
Nein, eine Unit-lokale Variable ist ja auch global. Das Problem daran ist, dass es die Variable nur einmal gibt - du musst also sicherstellen, dass du nicht die Daten überschreibst, bevor der Hauptthread sie abgeholt hat. Für den Heap brauchst du New und Dispose bzw. GetMem und FreeMem.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: Threads verwalten

  Alt 22. Nov 2009, 16:24
unitlokal/global = heap
prozedurlokal = stack

du mußt aber aufpassen, daß der Speicher nicht wieder überschrieben wird.

z.B. mehrmals PostMessage mit diesem Speicher, aber das "Ziel" hat die gesendeten Nachrichten noch garnicht verarbeitet und somit würde der Speicher zurüh überschrieben.

Du kannst aber z.B. mit GetMem Speicher reservieren, mit PostMessage versenden und am "Ziel" diesen Speicher dann wieder freigeben.
(aber Achtung: einige Speichermanager muß man erst in einen Threadsicheren Modus versetzen, aber ich hoffe mal, daß dieses bei dir schon der Fall ist)
$2B or not $2B
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#6

Re: Threads verwalten

  Alt 22. Nov 2009, 16:27
Hm? "Heap" ist doch normalerweise nur der Bereich, der vom Speichermanager verwaltet wird, und das ist bei globalen Variablen nicht der Fall. Kann aber sein, dass ich mich hier in der Terminologie irre.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
taaktaak

Registriert seit: 25. Okt 2007
Ort: Radbruch
1.993 Beiträge
 
Delphi 7 Professional
 
#7

Re: Threads verwalten

  Alt 22. Nov 2009, 16:35
Danke, bisher funktioniert das alles recht gut!
Meine Anwendungsfälle sind allerdings nicht thread-bezogen, ich verwende das Verfahren um Nachrichten zwischen Units auszutauschen, die sich nicht kennen. So versendet z.B. die Konfiguration eine neu gesetzte Farbe und alle Units, die sich berufen fühlen, aktualisieren dann ausgewählte Controls.

Äh, ja, ein Widerspruch ist da.
Würde aber aufgrund fehlender Fehler (hihi) zu himitsu's Erklärung tendieren
Ralph
  Mit Zitat antworten Zitat
David Martens

Registriert seit: 29. Sep 2003
205 Beiträge
 
Delphi XE Enterprise
 
#8

Re: Threads verwalten

  Alt 23. Nov 2009, 00:49
Um auf die ursprüngliche Frage zurückzukommen, ja die Frage ist sehr allgemein.

So weit ich jetzt verstanden habe kann ich also eine Klasse wie die erstellen:
Delphi-Quellcode:
TWatchThread = class(TThread)
private
  FileNotify : TfisFileNotification;
  FileZip : TJvZlibMultiple;

  Name,
  WatchFolder,
  BackupFolder : string;
  IncludeFiles,
  ExcludeFiles,
  ExcludeFolder : string;
  minSize,
  maxSize : integer;

  procedure OnNotifyChanged(Sender: TObject);
public
  constructor Create(AOwner : TComponent);
  
  procedure Execute; override;
end;

procedure TWatchThread.Execute;
begin
  FileNotify.Start;
  ...
  FlieNotify.OnChanged := OnNotifyChanged;
end;

procedure TWatchThread.OnNotifyChanged(Sender: TObject);
begin
  // auf den Event reagieren
  // Liste der Dateien durchgehen, Änderungen mit FileZip speichern
  
  // So hier die Meldung für das Log ???
  PostMessage(MainForm.Handle, MY_WM_USER, SUB_MESSAGE_NEW_SAVE, Integer(InfoRecord));
end;
Und dann kann ich die TWatchThread Objekte einfach in eine TObjectList speichern?

Delphi-Quellcode:
// Threads erstellen
begin
  ObjectList := TObjectList.Create;
  ObjectList.OwnsObjects := true;

  // für alle zu überwachende Verzeichnisse
  ObjectList.Add(TWatchThread.Create(Self));
end;

// Threads starten
begin
  aWatchThread := TWatchThread(ObjectList.Items[index]);
  aWatchThread.Execute;
end;
Ich muß natürlich noch auf die Messages reagieren, aber hab ich das so richtig gemacht?

Danke David
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: Threads verwalten

  Alt 23. Nov 2009, 08:31
Man ruft .Execute nicht direkt auf!
Und wo wie/wo ist InfoRecord definiert?
$2B or not $2B
  Mit Zitat antworten Zitat
David Martens

Registriert seit: 29. Sep 2003
205 Beiträge
 
Delphi XE Enterprise
 
#10

Re: Threads verwalten

  Alt 23. Nov 2009, 17:41
Delphi-Quellcode:
  
  PInfoRecord = ^TInfoRecord ;
  TInfoRecord = record
                   WatchThreadID : Cardinal;
                   Meldung : string;
                 end;

procedure TWatchThread.OnNotifyChanged(Sender: TObject);
var
  InfoRecord : PInfoRecord;
begin
  // auf den Event reagieren
  // Liste der Dateien durchgehen, Änderungen mit FileZip speichern
 
  // Also so ???
  New(FoundRecord);
  InfoRecord^.WatchThreadID := GUID;
  InfoRecord^.Meldung := 'Hier kommt der Text für die Meldung rein';
  
  PostMessage(MainForm.Handle, MY_WM_USER, SUB_MESSAGE_NEW_SAVE, Integer(InfoRecord));
end;

procedure TMainForm.ThreadMessage( var Message : TMessage );
var
  InfoRecord : PInfoRecord;
  ID : Cardinal;
begin
  case Message.WParam of

    MY_WM_USER :
      begin
        InfoRecord := PInfoRecord(Message.LParam);
        ID := ThreadIDToIndex( InfoRecord^.WatchThreadID );
        Memo.Lines.Add(InfoRecord^.Meldung);
        Dispose(InfoRecord);
      end;

end;
Sohier dachte ich.
  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 15:22 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