Einzelnen Beitrag anzeigen

Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#13

AW: TThread Suspend und Resume

  Alt 15. Sep 2016, 01:15
Da in dem Artikel darauf hingewiesen wird, dass Windows XP Condition-Variables nicht unterstützt, wir dieses aber noch unterstützen müssen, wäre ich daran interessiert wie du das dann machen würdest.
Events sehen in der Richtung gut aus. Da die aber beim Warten keine CS freigeben können und nicht zählen, muss man aufpassen mit Deadlocks und vergessenen Wake-ups. Semaphoren können dir das Zählen abnehmen, machen aber auch nicht alles einfacher ... und für jedes Zählen wechselt man in das Betriebssystem.

Im Prinzip könnte das so aussehen (Pseudocode, ungetestet):
Delphi-Quellcode:
var
  cs : CriticalSection;
  ev : Event; // als auto-reset konfiguriert
  count : Integer;

procedure producer()
begin
  while (true) do
  begin
    //> Hier etwas sinnvolles machen!

    EnterCriticalSection(cs);

    // Einen Eintrag in die Queue einhängen:
    count := count + 1

    // Hier ist die Bedingung immer erfüllst,
    // aber das muss nicht bei allen denkbaren Synchronisationsmustern so sein.
    if (count > 0) then setEvent(ev); // Aufwecken!
    LeaveCriticalSection(cs);
  end;
end;

procedure consumer()
begin
  while (true) do
  begin
    EnterCriticalSection(cs);
    while (not (count > 0)) do
    begin
      // Wir verlassen die CS, damit der Producer was einhängen kann.
      LeaveCriticalSection(cs);
      WaitForSingleObject(ev); // Schlafen!
      EnterCriticalSection(cs);
    end;

    // Jetzt ist count > 0 und wir haben die CS!
    // Also können wir hier z.B. etwas aus der Queue aushängen:
    count := count - 1;

    // Bevor wir die CS verlassen, gucken wir noch mal, ob die Bedingung weiter erfüllt ist
    // und wecken gegebenenfalls noch den nächsten auf.
    if (count > 0) then setEvent(ev);
    LeaveCriticalSection(cs);
    
    //> Hier etwas sinnvolles machen!
  end;
end;
Das Event dient quasi als Condition-Variable, die CS schützt die Queue bzw. hier nur den Zähler. Man kann und sollte das Ganze in eine Queue-Implementierung kapseln, wenn man damit sinnvoll arbeiten möchte.

Disclaimer: Ich habe mich nicht eingehend mit den konkreten Windows Synchronisationsfunktionen befasst. Synchronisation ist schwer und fehleranfällig. Bitte auf Fehler/Bedenken hinweisen.
Intellekt ist das Verstehen von Wissen. Verstehen ist der wahre Pfad zu Einsicht. Einsicht ist der Schlüssel zu allem.
  Mit Zitat antworten Zitat