AGB  ·  Datenschutz  ·  Impressum  







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

Frage zu Thread und Ciritical Section

Ein Thema von McMorton · begonnen am 23. Apr 2006 · letzter Beitrag vom 27. Apr 2006
Antwort Antwort
Seite 1 von 2  1 2      
McMorton

Registriert seit: 8. Mär 2006
45 Beiträge
 
#1

Frage zu Thread und Ciritical Section

  Alt 23. Apr 2006, 21:00
Hallo.

Ich habe eine Frage zum Thema Threads.

Ich habe einen Thread, der über eine Critical Section auf ein Element zugreift.
Ein anderes Objekt will ab und zu ebenfalls auf dieses Element zugreifen (ebennfalls über Critical Section).

Nun habe ich beim ersten Test festgestellt, das das Objekt nie Zeit bekommt zuzugreifen. Der Thread läuft ständig, und belegt die ganze Zeit die Critical Section.
Wenn ich eine kurze Pause im Thread einfüge, dann geht es. Aber nun läuft das Programm irgentwie "unrund". Wenn ich die Form mit der Maus verschieben will, bewegt es sich sehr hagelig.
Liegt das an dem Sleep Befehl?
Wie kann ich das Problem sonst lösen?

Hier der Code:

Delphi-Quellcode:
//Der Thread
procedure einThread.execute;
begin
  while not Terminated do
    begin
      try
        //Pause, ansonsten würde eine andere Critical Section keine Zeit bekommen
        sleep(20);
        FCritSect.Enter;
          //Zugriff auf ein Objekt (Lesefunktion von Indy10)
        FCritSect.Leave;
      except
      end;
    end;
end;


//Das andere Objekt
procedure Datensenden;
begin
  try
    self.FCritSect.Enter;
      //Zugriff auf ein Objekt (Schreifunktion von Indy10)
    self.FCritSect.Leave;
  except
  end;
end;
  Mit Zitat antworten Zitat
guste

Registriert seit: 23. Apr 2006
19 Beiträge
 
#2

Re: Frage zu Thread und Ciritical Section

  Alt 23. Apr 2006, 21:39
spontan fällt mir dazu finally statt except ein:

Delphi-Quellcode:
//Der Thread
procedure einThread.execute;
begin
  while not Terminated do
    begin
      try
        //Pause, ansonsten würde eine andere Critical Section keine Zeit bekommen
        sleep(20);
        FCritSect.Enter;
          //Zugriff auf ein Objekt (Lesefunktion von Indy10)
      finally
        FCritSect.Leave;
      end;
    end;
end;


//Das andere Objekt
procedure Datensenden;
begin
  try
    self.FCritSect.Enter;
      //Zugriff auf ein Objekt (Schreifunktion von Indy10)
  finally
    self.FCritSect.Leave;
  end;
end;
  Mit Zitat antworten Zitat
tigerman33

Registriert seit: 30. Jul 2005
Ort: München
423 Beiträge
 
Delphi 2005 Professional
 
#3

Re: Frage zu Thread und Ciritical Section

  Alt 24. Apr 2006, 09:14
Wenn das andere Objekt Zugriff auf den Thread hat, könnte es diesen per Suspend schlafen legen und dann auf das Objekt zugreifen.
Eleganter fände ich allerdings, wenn dein Objekt quasi "anmeldet", dass es gerne schreiben möchte und daraufhin der Thread dementsprechend Rücksicht nimmt. Würde im Endeffekt so ziemlich auf das gleiche hinauslaufen wie ein Suspend, nur etwas anders verpackt.
Christian
Der Computer hilft mir, Probleme zu lösen, die ich ohne Computer nicht hätte.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: Frage zu Thread und Ciritical Section

  Alt 24. Apr 2006, 09:47
Wenn der andere Thread nur manchmal (selten) auf das Objekt zugreift, dann könntest du ihm ja sowas wie MasterRecht geben, damit er vorrangig auf das Objekt zugreifen kann.
Hab aber keine Ahnung, ob sowas mit CiriticalSections möglich ist, da ich meine eigenen (nicht so überladenen) Methoden verwende Objekte/Speicherbereiche Threadsave zu machen ._.
$2B or not $2B
  Mit Zitat antworten Zitat
mbamler

Registriert seit: 19. Mai 2005
Ort: Hamburg
118 Beiträge
 
Delphi 7 Architect
 
#5

Re: Frage zu Thread und Ciritical Section

  Alt 24. Apr 2006, 10:07
Zitat von himitsu:
Wenn der andere Thread nur manchmal (selten) auf das Objekt zugreift, dann könntest du ihm ja sowas wie MasterRecht geben, damit er vorrangig auf das Objekt zugreifen kann.
Hab aber keine Ahnung, ob sowas mit CiriticalSections möglich ist, da ich meine eigenen (nicht so überladenen) Methoden verwende Objekte/Speicherbereiche Threadsave zu machen ._.

Benutz doch Synchronize()
Das ist extra geschaffen, um in kritischen Abschnitten Threads die Kommunikation mit
andren Threads (so auch den Mainthread) zu ermöglichen...

Gruß
Matthias
  Mit Zitat antworten Zitat
McMorton

Registriert seit: 8. Mär 2006
45 Beiträge
 
#6

Re: Frage zu Thread und Ciritical Section

  Alt 24. Apr 2006, 23:35
Erstmal Danke für die Antworten.

Mir ist aufgefallen: sobald ich den Sleep-Befehl entferne, steigt die CPU-Auslastung auf 100%.

Aber hagelig bewegt sich die Form immer noch. Sobald ich den Thread stoppe läßt sie sich flüssig verschieben.
  Mit Zitat antworten Zitat
HolgerX

Registriert seit: 10. Apr 2006
Ort: Leverkusen
972 Beiträge
 
Delphi 6 Professional
 
#7

Re: Frage zu Thread und Ciritical Section

  Alt 25. Apr 2006, 05:57
Hallo,
hmm...
Zitat von McMorton:
Mir ist aufgefallen: sobald ich den Sleep-Befehl entferne, steigt die CPU-Auslastung auf 100%.

Aber hagelig bewegt sich die Form immer noch. Sobald ich den Thread stoppe läßt sie sich flüssig verschieben.
Welche Priorotät hast Du deinem Thread gegeben ?
Gib im mal eine geringere und bedenke, das dieser Thread eigendlich immer im Prozess des MainThread läuft.
Solltest Du nur ein 'gelegendliches Prüfen benötigen, dann währe hier wohl eine einfache TTimer - Verwendung sinnvoller.

Ach ja das 'hagelige' Bewegen kommt einfach durch die Verarbeitung des Zugriffes innerhalb der critical Section, da der MainThread dafür unterbrochen wird (ähnlich wie Synchronize)!

Schuiii...

Holger
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#8

Re: Frage zu Thread und Ciritical Section

  Alt 25. Apr 2006, 08:25
Dein Ansatz ist falsch, die Idee mit dem Suspend im Prinzip richtig, aber leider auch im Detail falsch.
Erstmal ist aber korrekt, das der eine Thread nun nicht non-stop per Critical-Section auf den geschützten Bereich zugreifen muss, denke ich. Normalerweise sehen Threads doch so aus
Delphi-Quellcode:
Procedure TMyThread.Execute;
Begin
  While Not Terminated Do Begin
    WaitForSomethingToDoOrTerminated;
    If SomethingToDo Then DoIt;
 End;
End;
Willst Du z.B. ein Spiel programmieren, würde ein Timer dem Thread periodisch sagen können 'Do something': Der Thread erledigt diesen Job und wartet dann wieder auf den Nächsten. tigerman33 hat schon die Idee mit dem suspend gehabt, aber das ist unsauber, da man ja nicht weiss, was der Thread gerade macht. Besser ist es, über ein Synchronisationsobjekt mit dem Thread zu kommunizieren. Da wäre eine Semaphore oder ein Event gerade das Richtige. Die Funktion, die darauf wartet, das Synchronisationsobjekt (SO) ein Signal bekommt, heißt 'WaitForSingleObject' und... tut genau das: Es wartet, bis jemand das SO antriggert, und das sehr effizient (also mit 0% CPU-Last).

Ich arbeite mit Semaphoren. Eine Sempahore ist soetwas wie ein Zähler, der absolut threadsicher verwaltet wird. Wenn der Zähler 0 ist, dann wartet 'WaitForSingleObject' (WFSO). Sobald der Zähler>0, wird WFSO beendet und der Zähler um eins dekrementiert. WFSO wartet also, BIS der Zähler > 0 ist. Ist die Semaphore bereits > 0 beim Aufruf, wird die Semaphore sofort dekrementiert und WFSO beendet.

Die Semaphore wird mit 'ReleaseSemaphore' gesteuert.

Also:
1. CreateSemaphore im Create des Threads, CloseHandle im Destruktor.
2. WaitForSingleObject im Execute des Threads (lies genau die Möglichkeiten des Timeouts in der OH)
3. ReleaseSemaphore signalisiert, das der Thread einen Job zu erledigen hat.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
McMorton

Registriert seit: 8. Mär 2006
45 Beiträge
 
#9

Re: Frage zu Thread und Ciritical Section

  Alt 26. Apr 2006, 00:11
Das mit der Semaphore versteh ich leider nicht.
So wie ich es zu verstehen gleube soll meine Hauptanwendung dann über diese Hilfsklasse den Thrad anstoßen?
Das bring mit aber leider nichts.
Meine Hauptklasse hat keine Ahnung wann es was zu tun gibt (ich lese im Thread Daten über die Indy-Komponente ein).

Ich habe es momentan so gelöst, das ich ein WaitForSingeObject(self.Handle, 20) verwende.
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#10

Re: Frage zu Thread und Ciritical Section

  Alt 26. Apr 2006, 07:49
Der Thread wird aber doch nicht ständig Daten einlesen, sondern muss auch warten, *bis* Daten vorhanden sind. Dann ist eben nicht das Hauptprogramm zuständig, den Thread anzustoßen, sondern Windows bzw. die Indy-Komponente. Die hat doch mit Sicherheit ein Event 'OnData', oder?
Es gibt nur sehr wenige Außnahmen, wo ein Thread wirklich nonstop rechnen muss: Bei aufwändigen Berechnungen etwa, oder bei Echtzeitspielen.

I/O ist doch gerade dafür geschaffen, im Hintergrund 'en passant' abgewickelt zu werden, denn die meiste Zeit wartet man doch sowieso, bis endlich mal wieder ein Byte vorbeihuscht.

Man muss sich unter Windows davon verabschieden, in der klassischen Art und Weise I/O zu programmieren (nämlich durch polling). Statt dessen sagt man Windows, wen und was es aufrufen soll, *wenn* etwas passiert, also wenn z.B. Daten angekommen sind. Auch wenn man sich auf ein 'Read' setzt, passiert im Hintergrund nichts anderes.

Die ICS-Komponenten von Francois Piette (www.overbyte.be) sind komplett auf Events aufgebaut und damit asynchron und einfach als Komponenten zu verwenden. Der Nachteil an der Sache ist dann aber, das man Zustandsautomaten programmieren muss. Bei der SMPT-Komponente (emails lesen) muss man das Ereignis 'OnGetData'. Dieser Event wird immer ausgelöst, wenn etwas vom EMail-Server zurückkommt. Man programmiert also nur, wie sich die Anwendung verhalten soll. Damit kann dann das Versenden einer EMail wirklich parallel zum Hauptprogramm erfolgen, ohne auch nur einen einzigen Thread geschrieben zu haben.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  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 09:46 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