AGB  ·  Datenschutz  ·  Impressum  







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

Synchronize mit Argumenten

Ein Thema von Viktorii · begonnen am 9. Feb 2011 · letzter Beitrag vom 10. Aug 2011
Antwort Antwort
Seite 3 von 5     123 45      
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#21

AW: Synchronize mit Argumenten

  Alt 11. Feb 2011, 00:05
@Sir Rufo

ich war schon vorher Deiner Meinung, meine Thread-Templates sind auch so aufgebaut.
Mir ging es nur darum festzustellen dass es wohl jedes mal abzuwägen gilt welche der Varianten (Queue/Synchronize) für den Anwendungsfall gerade sinnvoll ist.
Zitat:
Ich würde aber so gut wie immer statt Synchronize den Queue verwenden (manchmal muss halt Sync sein, aber beim reinen Abliefern von Informationen ...).
Es gibt IMHO auch Anwendungsfälle in denen z.B. kein Messwert verloren gehen darf (also durch einen späteren ersetzt werden).

BTW leicht offtopic, wie handhabst Du Syncs zwischen Threads und SubThreads (oder nebenläufigen Threads), also ohne Umweg über den Anwendungsthread?
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  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
 
#22

AW: Synchronize mit Argumenten

  Alt 11. Feb 2011, 01:29
Wieso gehen beim Queue Werte verloren? Klar, wenn man es falsch macht ja, aber wenn ich das Auto nicht richtig beherrsche fahre ich evtl. auch gegen den Baum.
Also am besten richtig machen

Bei meinen Queues gehen keine Werte verloren.
(und seit der anonymen Methoden geht halt auch das Queue ohne eigene Warteschlange)

Wichtig ist nur am Ende des Threads ein Synchronize zu machen, damit auch wirklich alle Queue-Einträge im Hauptthread verarbeitet wurden. Ansonsten kann es eben halt passieren, dass der Thread (FreeOnTerminate) sich einfach so auflöst und alle bis dahin nicht abgearbeitete Queue-Einträge aus selbigen Thread gehen sang und klanglos mit unter.

Zwischen den Threads (auch Hauptthread direkt zum Thread) geht das bei mir immer über eine CS.
Manchmal halt auch eine separate CS für den reinen Austausch dieser Daten, wenn es vom Ablauf geschickter ist und dadurch performanter wird.

ADD Daten von Thread zu Thread über den Hauptthread auszutauschen halte ich nicht für sinnvoll.
Der Hauptthread ist für den User und wird von dem quasi kontrolliert. Wenn der also Samba auf der Tastatur und Maus tanzt, dann könnte er damit auch die Threads beeinflussen.
Bei mir darf der das (wenn es nicht meine Maus/Tastatur ist)
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 (11. Feb 2011 um 01:37 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Synchronize mit Argumenten

  Alt 11. Feb 2011, 02:00
Wenn man zusammen mit dem Prozedurzeiger auch noch die Parameter mit in dem Queue ablegt, dann gäbt es diesbezüglich auch keine Probleme.

Bzw., man eh nur die selbe Funktion aufrugt, dann reichen auch nur die Werte im Queue, wenn nichts verlorengehen soll.
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#24

AW: Synchronize mit Argumenten

  Alt 11. Feb 2011, 08:42
Zitat:
Bei meinen Queues gehen keine Werte verloren.
(und seit der anonymen Methoden geht halt auch das Queue ohne eigene Warteschlange)
dann haben wir eine Kommunikationsproblem, oder ich einen Hänger, wie löst Du #16 mit Queue so dass Du alle erwarteten Werte zurückbekommst?
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Viktorii

Registriert seit: 19. Jul 2007
358 Beiträge
 
#25

AW: Synchronize mit Argumenten

  Alt 11. Feb 2011, 10:36
Ich steh immer noch auf dem Schlauch. Habe den Zugriff mit eine CS geschützt.

In dieser CS übertrage ich meine Daten an eine TQueue (Das erste mal dass ich mit Generics gearbeitet habe ) damit die Blockierung auf ein zeitliches Minimum begrenzt bleibt. Allerdings blockiert das Abarbeiten der Queue die Funktion und es gehen immer noch Werte 'verloren'.
Delphi-Quellcode:
type
  TValueQueue = TQueue<Integer>;

  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    FMyThread: TMyThread;
    FValueQueue: TValueQueue;
    procedure progress(value: Integer);
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Memo1.Clear;
  FValueQueue := TValueQueue.Create;
  FMyThread := TMyThread.Create(true);
  FMyThread.Progress := progress;
  FMyThread.Resume;
end;

procedure TForm1.progress(value: Integer);
begin
  FMyThread.SyncCS.Enter;
  FValueQueue.Enqueue(value);
  FMyThread.SyncCS.Leave;

  while FValueQueue.Count > 0 do
  begin
    Memo1.Lines.Add('Value: ' + IntToStr(FValueQueue.Dequeue));
    sleep(500);
  end;
end;
Delphi-Quellcode:
type
  TProgress = procedure(Value: integer) of object;

type
  TMyThread = class(TThread)
  private
    FValue: Integer;
    FProgress: TProgress;
    FSyncCS: TCriticalSection;
    procedure SyncProgress;
  protected
    procedure Execute; override;
  public
    property Progress: TProgress write FProgress;
    property SyncCS: TCriticalSection read FSyncCS;

  end;

implementation

uses
  Windows, SysUtils;
{ TMyThread }

procedure TMyThread.Execute;
var
  i: Integer;
begin
  FSyncCS := TCriticalSection.Create;
  for i := 1 to 10 do
  begin
    FSyncCS.Enter;
    FValue := i;
    FSyncCS.Leave;

    Queue(SyncProgress);
    sleep(200);
  end;
  //if assigned(FSyncCS) then
  // FreeAndNil(FSyncCS);
end;

procedure TMyThread.SyncProgress;
begin
  FProgress(FValue);
end;
Wie mache ich es richtig(er)?
  Mit Zitat antworten Zitat
Viktorii

Registriert seit: 19. Jul 2007
358 Beiträge
 
#26

AW: Synchronize mit Argumenten

  Alt 11. Feb 2011, 11:28
!!! OFF TOPIC !!!

Ist ja echt frustrierend RAD heißt doch Rapid Application Development. Und es heißt doch immer mit Delphi geht alles immer so einfach im Gegensatz zu cpp. Ich habe ein Embedded Projekt mit Qt geschrieben und dachte mir ich versuche jetzt mal ob ich bei Qt auch dieses Problem habe....

Und siehe da, alles ganz einfach. Keine zusätzlichen privaten Felder in denen die zu übergebenden Werte stehen, keine zusätzlichen CS, keine zusätzlichen Methoden, keine Generic Queue oder was weiß ich für Tricksereien und im Gegensatz zu meiner Lösung bei Delphi funktioniert diese Qt Lösung (auf Anhieb nach 10 min)

Code:
class MainWindow : public QMainWindow
{
    Q_OBJECT

   public:
      explicit MainWindow(QWidget *parent = 0);
      ~MainWindow();

   private slots:
      void on_pushButton_clicked();
      void onProgress(qint32);

   private:
      Ui::MainWindow *ui;
};


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{
   MyThread *myThread;

   myThread = new MyThread(this);

   connect(myThread,   SIGNAL(progress(qint32)),
         this,      SLOT(onProgress(qint32)));

   myThread->start();
}

void MainWindow::onProgress(qint32 value)
{
   ui->plainTextEdit->appendHtml("Value: " + QString::number(value));
   Sleep(500);
   qDebug() << QThread::currentThreadId() << "MainWindow::onProgress - Value:" << QString::number(value);
}
Code:
class MyThread : public QThread
{
    Q_OBJECT
   public:
      explicit MyThread(QObject *parent = 0);

   signals:
      void progress(qint32 value);

   public slots:

   protected:
      void run();

};


#include "MyThread.h"
#include <windows.h>
#include <QDebug>

MyThread::MyThread(QObject *parent) :
    QThread(parent)
{
}

void MyThread::run()
{
   for(qint32 i = 1; i <= 10; i++)
   {
      emit progress(i);
      Sleep(200);
      qDebug() << QThread::currentThreadId() << "MyThread::run() - Value:" << QString::number(i);
   }
   qDebug() << QThread::currentThreadId() << "Fertig";
}

Zitat:
0x14e8 MyThread::run() - Value: "1"
0x14e8 MyThread::run() - Value: "2"
0x13b4 MainWindow:nProgress - Value: "1"
0x14e8 MyThread::run() - Value: "3"
0x14e8 MyThread::run() - Value: "4"
0x13b4 MainWindow:nProgress - Value: "2"
0x14e8 MyThread::run() - Value: "5"
0x14e8 MyThread::run() - Value: "6"
0x14e8 MyThread::run() - Value: "7"
0x13b4 MainWindow:nProgress - Value: "3"
0x14e8 MyThread::run() - Value: "8"
0x14e8 MyThread::run() - Value: "9"
0x14e8 MyThread::run() - Value: "10"
0x14e8 Fertig
0x13b4 MainWindow:nProgress - Value: "4"
0x13b4 MainWindow:nProgress - Value: "5"
0x13b4 MainWindow:nProgress - Value: "6"
0x13b4 MainWindow:nProgress - Value: "7"
0x13b4 MainWindow:nProgress - Value: "8"
0x13b4 MainWindow:nProgress - Value: "9"
0x13b4 MainWindow:nProgress - Value: "10"
So, das musste mal raus. Jetzt gehts mir besser

Und wie mache ich es jetzt richtig in Delphi (siehe #25)?

Geändert von Viktorii (11. Feb 2011 um 11:31 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Synchronize mit Argumenten

  Alt 11. Feb 2011, 12:23
Du übergibst da aber den Wert direkt an den Thread, bzw du gibst jedem Thread eine Kopie, so daß alle Threads ihre eigenen Werte haben.

In diesen Delphibeispielen nutzt du eine externe Variable für alle Threads.

> Äpfel und Birnen
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#28

AW: Synchronize mit Argumenten

  Alt 11. Feb 2011, 12:27
@himitsu
und wie übergebe ich Delphi eine Kopie per Queue?
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

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

AW: Synchronize mit Argumenten

  Alt 11. Feb 2011, 13:10
Sir Rufo hat ja bereits auf den Artikel in meinem Blog verwiesen, der den Aufruf von Synchronize mit einer Anonymen Methode zeigt. Natürlich kann man dieses Verfahren 1:1 auch auf Queue anwenden (habe ich auch erwähnt).

Allerdings muss man dann aufpassen (habe ich am Ende des Artikels auch drauf hingewiesen), daß der Thread sich nicht bereits beendet bevor die Queues alle abgearbeitet wurden. Ansonsten gehen die letzten Einträge nämlich verloren (gilt aber für alle Implementationen, die Queue benutzen).

Der Vorteil der Anonymen Methode ist einfach, daß man sich um die Kapselung des Parameters keine Gedanken mehr machen muss - das erledigt der Compiler. Das ganze Brimborium mit der TValueQueue ist damit völlig überflüssig.

Ach ja: Sollte jemand Probleme haben, den Artikel zu vestehen, da er auf Englisch verfasst ist, könnte ich mich vielleicht dazu durchringen, eine Deutsche Fassung hier an geeigneter Stelle (wo?) bereitzustellen.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Viktorii

Registriert seit: 19. Jul 2007
358 Beiträge
 
#30

AW: Synchronize mit Argumenten

  Alt 11. Feb 2011, 14:39
Also ich bekomme es mit queue nicht hin.

Wie muss mein Code von #16 oder #26 abgeändert werden damit das funktioniert?

Könnte den korrekten code jemand evtl. posten? Wäre sehr dankbar!
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 5     123 45      


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 14:05 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