AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Synchronize inerhalb globaler Funktion durchführen
Thema durchsuchen
Ansicht
Themen-Optionen

Synchronize inerhalb globaler Funktion durchführen

Ein Thema von schwa226 · begonnen am 16. Feb 2011 · letzter Beitrag vom 17. Feb 2011
Antwort Antwort
Seite 1 von 2  1 2      
schwa226

Registriert seit: 4. Apr 2008
400 Beiträge
 
#1

Synchronize inerhalb globaler Funktion durchführen

  Alt 16. Feb 2011, 17:06
Hallo,

ich habe ein gleines Synchronize Problem!

Ich habe einen Thread der mir Daten in eine TThreadList reingibt oder rausnimmt.
Der Thread ruft nun die LockList auf und befindet sich somit in der Critical Section.
Wie kann ich aber nun in dieser Funktion auch noch die VCL updaten?

Ein einfaches zugreifen auf das Memo in der VCL statt einem Synchronize führt zu Problemen da der Thread zwar gegen andere Threads sicher ist, aber nicht mit der VCL im Sync ist.

Delphi-Quellcode:
procedure RemoveData(Data : Pointer);
var
  List : TList;
  i : Integer;
begin

  List := fStringList.LockList;

  try
    for i := 0 to List.Count - 1 do
    begin
      if List[i] = Data then
      begin
        List.Delete(i);
        ---> Synchronize(RemoveStringInMemo); ???????????????
      end;
    end;
  finally
    fStringList.Unlocklist;
  end;
end;
Delphi 2010, Update 4 & 5
  Mit Zitat antworten Zitat
Benutzerbild von Memnarch
Memnarch

Registriert seit: 24. Sep 2010
737 Beiträge
 
#2

AW: Synchronize inerhalb globaler Funktion durchführen

  Alt 16. Feb 2011, 17:11
Also ich versteh das problem nicht ganz o.O.
Mal kurz zum mitschreiben:
Du veränderst den inhalt einer stringlist, und nach dem manipulieren soll der inhalt mit dem Memo synchronisiert werden?

Fals ich obiges richtig verstanden habe:

Schreib ne prozedur die das macht und rufe die per Synchronize aus dem thread auf o.O

MFG
Memnarch
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.453 Beiträge
 
Delphi 12 Athens
 
#3

AW: Synchronize inerhalb globaler Funktion durchführen

  Alt 16. Feb 2011, 17:13
Man müsste jetzt noch sehen, wie RemoveStringInMemo herausfindet, welchen String es entfernen soll. Etwas mehr Code wäre hilfreich.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
schwa226

Registriert seit: 4. Apr 2008
400 Beiträge
 
#4

AW: Synchronize inerhalb globaler Funktion durchführen

  Alt 16. Feb 2011, 17:24
Ich habe natürlich den Code oben nur kurz reingetippt

Eigentlich ist die Funktion RemoveData in einer Class.
Wird die Funktion RemoveData von einem Thread aufgerufen wird aus der TThreadList das Item entfernt.

Danach wollte ich mit einer Funktion der Class ein Stringgrid in der Hauptform Updaten.
Beim AutoSizeGrid (anpassen der GridSpaltenbreite) was beim Updaten ausgeführt wird gibt es aber dann Probleme.

Ich habe jetzt auch versucht meiner Class den TThread zu übergeben, aber dann bekomme ich die Meldung das Synchronize protected ist.

Also kann Synchronize nur im Thread selber aufgerufen werden.
Ich hatte mir gedacht, ich kann eine Funktion machen, wo Daten der TThreadList bearbeitet werden und auch gleich das StringGrid in der VCL ein Update erhält.

Nun glaube ich, dass ich halt im Thread die TThreadList bearbeiten muss und dann noch extra im Thread danach das Synchronize durchführen muss.
Delphi 2010, Update 4 & 5
  Mit Zitat antworten Zitat
Benutzerbild von Memnarch
Memnarch

Registriert seit: 24. Sep 2010
737 Beiträge
 
#5

AW: Synchronize inerhalb globaler Funktion durchführen

  Alt 16. Feb 2011, 17:33
natürlich get Synchronize nur innerhalb eines Threads. Dieser funktion musst du dan die Funktion übergeben, die du synchronisieren möchtest(also z.B. die updatefunktion).

MFG
Memnarch
  Mit Zitat antworten Zitat
schwa226

Registriert seit: 4. Apr 2008
400 Beiträge
 
#6

AW: Synchronize inerhalb globaler Funktion durchführen

  Alt 16. Feb 2011, 17:47
Habe es nun so gemacht!

Ich gebe in eine Private Var meine Daten und rufe dann das Synchronize im Thread auf.
Dies Sync Procedure ruft mit dann die Globale funktion auf und schraubt am StringGrid herum.
Dann gibt es keine Probleme.

Wie sieht es nun aus, wenn ein Thread das Synchronize ausführt und darin das LockList durchführt und nun ein anderer Thread auch das Synchronize ausführen will.
Wartet da der zweite thread darauf, dass der erste die Sync Procedure wieder verlassen hat oder kann es hier einen Deadlock führen?
Delphi 2010, Update 4 & 5
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.453 Beiträge
 
Delphi 12 Athens
 
#7

AW: Synchronize inerhalb globaler Funktion durchführen

  Alt 16. Feb 2011, 19:19
Ohne den konkreten Code, kann ich immer noch nur raten...

Aber: Wenn innerhalb RemoveStringInMemo ein LockList aufgerufen wird, darfst du während du das Synchronize aufrufst keien Lock auf die Liste haben, sonst ahst du schon deinen DeadLock. Durch das Synchronize ist dein Thread blockiert und im HauptThread geht das Lock nicht durch.

Wenn immer nur ein Element aus der Liste entfernt wird, merk dir doch den Index und ruf Synchronize nach dem Unlock auf.

Eventuell kannst du auch statt Synchronize Queue aufrufen, aber das kann dann ganz andere Nebeneffekte haben. Es gibt eben keine generelle Regel.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Synchronize inerhalb globaler Funktion durchführen

  Alt 16. Feb 2011, 19:26
TThread bietet Synchronize in mehreren Varianten, einige als Klassen-Methode, welche man direkt über TThread.Synchronize(nil, MyProc); nutzen kann.

Entweder mit einer Prozedur (Delphi-Referenz durchsuchenTThreadProcedure) und womöglich mit einer globalen Variable (neuerdings auch als anonyme Methode),
oder als Methode (Delphi-Referenz durchsuchenTThreadMethod) irgendeiner Klasse, mit einem Feld in dieser Klasse.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  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: Synchronize inerhalb globaler Funktion durchführen

  Alt 16. Feb 2011, 19:49
Wie sieht es nun aus, wenn ein Thread das Synchronize ausführt und darin das LockList durchführt und nun ein anderer Thread auch das Synchronize ausführen will.
Wartet da der zweite thread darauf, dass der erste die Sync Procedure wieder verlassen hat oder kann es hier einen Deadlock führen?
Deadlock gibt es nicht ... weil das Locken auch nichts bringt.

Eine CriticalSection darf unter der gleichen ThreadID sooft betreten werden wie man lustig ist.
Und wenn der Aufruf per Sync erfolgt, dann befindest du dich im Kontext von MainThreadID!

Somit bringt dir die CriticalSection da nix ausser verschwendete Bytes im Source und Code.

Wer es nicht glaubt das geht und wird auch immer brav aufgerufen
Delphi-Quellcode:
procedure RemoveData(Data : Pointer);
var
  List : TList;
  i : Integer;
begin
  // Da aus dem Thread mit Sync aufgerufen wird
  // ist diese Bedingung immer erfüllt
  // und kann daher auch entsorgt werden
  if MainThreadID = GetCurrentThreadID then
  begin

      for i := 0 to List.Count - 1 do
      begin
        if List[i] = Data then
        begin

          List.Delete( i );
          // Hier noch der Aufruf zur Aktualisierung des Memos
        end;
      end;

  end;
end;
Es ist auch immer hilfreich an gewissen Stellen mit OutputDebugString oder dem Schreiben einer Log-Datei oder mit einem Haltepunkt im Debugger die Statuswerte zu prüfen.
(z.B. GetCurrentThreadID und MainThreadID )
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 (16. Feb 2011 um 19:52 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Synchronize inerhalb globaler Funktion durchführen

  Alt 16. Feb 2011, 20:21
Zitat:
Wie sieht es nun aus, wenn ein Thread das Synchronize ausführt und darin das LockList durchführt und nun ein anderer Thread auch das Synchronize ausführen will.
Abgesehn davon, daß eh nur eine der Synchronize-Prozeduren gleichzeitig ausgeführt wird.
Also wenn ein Thread ein LockList macht, dann sollte er das am Ende auch wieder freigeben und nachdem dieser Synchronizeaufruf fertig abgearbeitet wurde, erst dann wird das andere Synchornize ausgefphrt und die Liste wäre ja schonwieder frei.
Gut, und zusärtlich das schon erwähnte Verhalten der CS, welche praktisch nur für andere Threads sperrt ... Synchronize-Prozeduren laufen ja immer im Hauptthread (dem der VCL) ab.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  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 18:36 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