Announcement

Collapse
No announcement yet.

Pollen mehrerer Kanäle mit Threads

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Pollen mehrerer Kanäle mit Threads

    Hallo Leute,

    ich habe noch nicht allzuviel Erfahrung was das Programmieren von Threads angeht und bin mir nicht sicher, ob Threads überhaupt die richtige Methode für meine Problem sind.

    Ich habe eine Oracle-Datenbank die sich mit der SPS-Steuerung einer Förderanlage unterhalten soll. In der Anlage gibt es ca. 30 bestimmte Punkte, an denen Daten mit der DB ausgetauscht werden müssen.

    In so einem Fall sendet die SPS eine bestimmtes Kennzeichen und eine Nummer in einem vorher definierten "Übergabefach". Diese Nummer verweist auf einen Datensatz in der Datenbank, dessen Inhalte nun upgedatet oder in das Übergabefach geschrieben werden sollen.
    Nach Beendigung dieser Aktion sendet das Delphi-Programm seinerseits ein Kennzeichen und die SPS kann beim nächsten zyklischen Durchlauf weiterarbeiten.

    Anschließend wird eine Weile gewartet und das Delphi-Programm überprüft ob das bereits erwähnte Kennzeichen im „Übergabefach“ eine erneute Bearbeitung erforderlich macht.

    Ist es sinnvoll für jeden Kanal einen Thread zu spendieren? Der Vorteil läge darin, daß bei einem Fehler (egal ob DB, Delphi oder SPS) nur ein „Übergabefach“/Kanal gestört wäre. Aber sind 30 Threads nicht zu mächtig??

    Also, falls jemand Ideen oder Kommentare hat: Immer her damit.....

    Vielen Dank schon im vor raus

    Hilmar Sackmann

  • #2
    Im Prinzip sollten 30 Threads kein Problem darstellen.
    Jeder Thread tut nichts weiter als auf sein Fach zu lauern und dabei fleissig mit Sleep zu schlafen. Der Rechenzeitverbrauch des Threads ist dann praktisch Null. Signalisiert die SPS eine Datenuebergabe, dann schaufelt der Thread die Daten von oder zur SPS und legt sich wieder auf die Lauer.<br>
    Inwieweit Datenbankverbindungen in Threads Probleme bereiten koennen weiss ich nicht

    Comment


    • #3
      Danke für die schnelle Antwort. Ich werde mein Glück mal in einer Test-Appl versuchen...

      Comment


      • #4
        Dann denk aber dran das die Threads Datenbankverbindungen (Komponenten auf der MainForm) nur mit Synchronize benutzen sollten. Alternativ jedem Thread seine eigene lokale Verbindung spendieren

        Comment


        • #5
          Hast Du mal ein Beispiel, ausn dem sowohl synchronize wie auch die Sache mit dem sleep hervor geht??

          Comment


          • #6
            Hallo,

            das folgende Beispiel demonstriert, wie ein Thread eine Datenmenge einsammeln und über Synchronize threadsicher an den primären Thread der VCL übergeben kann:
            <pre>
            { ************************************************** **************
            Source File Name : DBThreadMainForm2.pas
            Typ : Formular-Unit
            Autor : Andreas Kosch
            Erstellt am : 06.02.97
            Compiler : Delphi 3.0
            Betriebssystem : Windows 95
            Beschreibung : Demonstriert die SQL-Abfrage über einen
            zweiten Thread.
            Verwendet den Alias "ShareManager".
            Revisionen : 14.06.97 Test Delphi 3 Professional
            ************************************************** ************** }

            unit DBThreadMainForm2;

            interface

            uses
            Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
            DBTables, Db, Grids, DBGrids, ExtCtrls, DBCtrls, StdCtrls, Buttons;

            type
            TFormMain = class(TForm)
            SessionBDE: TSession;
            SessionQuery: TSession;
            DatabaseBDE: TDatabase;
            DatabaseQuery: TDatabase;
            TableBDE: TTable;
            DataSourceBDE: TDataSource;
            DBNavigator1: TDBNavigator;
            DBGrid1: TDBGrid;
            TableBDEID: TAutoIncField;
            TableBDEAktie: TStringField;
            TableBDEMinWert: TCurrencyField;
            TableBDEMaxWert: TCurrencyField;
            TableBDEAktuellerKurs: TCurrencyField;
            QueryKurs: TQuery;
            QueryKurskursmin: TCurrencyField;
            QueryKurskursmax: TCurrencyField;
            QueryKurskursavg: TCurrencyField;
            BitBtnClose: TBitBtn;
            DataSourceKurs: TDataSource;
            DBGrid2: TDBGrid;
            procedure DataSourceBDEDataChange(Sender: TObject; Field: TField);
            procedure BitBtnCloseClick(Sender: TObject);
            private
            { Private declarations }
            public
            { Public declarations }
            end;

            (* Das Thread-Objekt für die SQL-Abfrage *)

            TQueryKursThread = class(TThread)
            private
            { Private declarations }
            FAktieID : Integer; // Master-Detail-Verknüpfung
            FQuery : TQuery; // Handle auf TQuery im Formular
            FDS : TDataSource; // Handle auf TDataSource im Formular
            procedure ShowThreadValues; // Synchronize-Methode
            protected
            procedure Execute; override; // TThread.Execute ist abstrakt !
            public
            constructor Create(Query : TQuery;
            iID : Integer;
            DS : TDataSource); virtual;
            end;

            var
            FormMain: TFormMain;

            implementation

            {$R *.DFM}

            constructor TQueryKursThread.Create(Query : TQuery;
            iID : Integer;
            DS : TDataSource);
            begin
            // TThread-Instanz im angehaltenen Zustand erzeugen
            inherited Create(True);
            // Aktien-ID zuweisen
            FAktieID := iID;
            // TQuery-Handle sichern
            FQuery := Query;
            // TDataSource-Handle sichern
            FDS := DS;
            // TThread-Objekt soll sich selbst zerstören
            FreeOnTerminate := True;
            // Thread soll seine Arbeit aufnehmen
            Resume;
            end;

            procedure TQueryKursThread.Execute;
            begin
            // Sonderfall: keine ID übergeben -> kein Start
            if FAktieID = 0 then Exit;
            FQuery.Close;
            // Master-Detail-Beziehung der Tabellen nachbilden
            FQuery.Params[0].Value := FAktieID;
            // SQL-Abfrage starten
            FQuery.Open;
            Synchronize(ShowThreadValues);
            end;

            procedure TQueryKursThread.ShowThreadValues;
            begin
            // TDataSource-Komponente für TDBGrid aktivieren
            FDS.DataSet := FQuery;
            end;

            {----------------------------------------------------------}
            { Formular-Methoden }
            {----------------------------------------------------------}

            procedure TFormMain.DataSourceBDEDataChange(Sender: TObject; Field: TField);
            begin
            TQueryKursThread.Create(QueryKurs, // TQuery
            TableBDEID.Value, // ID-Wert der Aktie
            DataSourceKurs); // TDataSource für TDBGrid
            end;

            procedure TFormMain.BitBtnCloseClick(Sender: TObject);
            begin
            Close
            end;

            end.
            </pre>
            Der Aufruf von Sleep ist ganz einfach. Der folgende Aufruf legt den Thread für 1 Sekunde schlafen:
            <pre>
            ...
            Sleep(1000);
            ...
            </pre>

            P.S: Mit welcher Delphi-Version wird gearbeitet? Falls Delphi 6 zum Einsatz kommt, bitte das Kleingedruckte zu TThread.Synchronize gründlich durcharbeiten :-

            Comment


            • #7
              Hallo Andreas,<br>in der Schule verwende wir D6.02. In der Hilfe konnte ich nix Kleingedrucktes finden. Wo steht denn das Kleingedruckte

              Comment


              • #8
                Hallo,

                &gt;Wo steht denn das Kleingedruckte?

                zum einen in der ReadMe.txt und zum anderen in mehreren Beiträgen der Community-Webseite von Borland:<br>
                - http://community.borland.com/article/0,1410,27655,00.html<br>
                - http://community.borland.com/article/0,1410,28599,00.html<br>
                - http://www.geocities.com/delphihelp/info/ThreadInfo.htm (inoffizielle Borland-Webseite

                Comment


                • #9
                  Vielen Dank für das Beispiel....

                  Ich nutze Delphi 5 und die DOA-Komponenten von AllroundAutomations für den Zugriff auf die Oracle Datenbank.

                  Schaun wir mal wie das funktioniert..

                  Comment

                  Working...
                  X