![]() |
mehrere Thread-Instanzen
Hallo,
ich hab folgendes Problem: Ich hab einen Thread, welcher für die Datenerfassung eines Gerätes zuständig ist,das funktioniert auch tadellos. Allerdings möchte ich mehrere Geräte betreiben, d.h. ich hab ein array mit diesem thread. Beim Initialisieren wird auch jeder thread, wie es aussieht, kreiert. Allerdings ist dann tatsächlich nur einer diese Threads vorhanden. Die Deklaration:
Delphi-Quellcode:
Das Initialisieren:
type datarray = record
T, S : Double; end; type devicerec = record PORT : TPort; BAUD : TBaudRate; STOP : TStopBits; DATA : TDataBits; PARITY : TParityBits; FLOW : TFlowControl; end; var devicearr : array of record STATE : integer; THREAD : devThread; DATA : array of datarray; end;
Delphi-Quellcode:
Das kreieren des Threads:
for i := 0 to devcount-1 do
with devicearr[i] do begin THREAD := devThread.create(i); STATE := 0; end;
Delphi-Quellcode:
Vielen Dank für Eure Hilfe!!!
constructor devThread.create(arrid:integer);
begin inherited create(False); myid := arrid; end; |
Re: mehrere Thread-Instanzen
Wie viele elemente hat das Array? Du hast ein dynamisches Array definiert, dessen Länge Du zunächst mit SetLength festsetzt.
|
Re: mehrere Thread-Instanzen
Die Threads sollten schon alle da sein, sie sind nur alle suspended
|
Re: mehrere Thread-Instanzen
Es ist ein dynamische Array und ich setze die länge (der Einfachkeit halber) erstmal auf 2. Ich kreiere die Threads nicht suspended, mit nur einem Thread funktioniert es ja wunderbar! Die Threads sollten also sofort loslaufen.
|
DP-Maintenance
Dieses Thema wurde von "Matze" von "Programmieren allgemein" nach "Sonstige Fragen zu Delphi" verschoben.
Delphi-Frage |
Re: mehrere Thread-Instanzen
Sorry mein Fehler ;) war wohl schon zu spät für eine Vernünftige Antwort!
Also zu den dynamischen Arrays würde ich dir folgendes empfehlen:
Delphi-Quellcode:
Damit bist Du immer auf der sicheren Seite!
for i := Low(devicearr) to high(devicearr) do
begin ... end; Wenn das alles passt ist die nächste Frage natürlich was du in deinem Thread eigentlich machst, denn es könnte sein, dass deine Threads einfach gleich wieder beendet werden (ich nehm mal an WaitCommEvent?).... |
Re: mehrere Thread-Instanzen
Blanke Spekulation: Wenn die Threads allesamt sofort loslaufen, hast du doch keine Chance, ihnen jeweils einen anderen Comport zuzuweisen... Sie greifen also alle auf den selben COM zu - was evtl zu einer Exception führt und den Thread sofort wieder abbricht - oder du hast den Fall abgefangen und beendest den Thread ordentlich.
So oder so werden die Threads sofort terminiert und aus dem Speicher geworfen - existieren also nur ein paar Millisekunden. |
Re: mehrere Thread-Instanzen
Zitat:
Also: Wo gibts die Glaskugeln??? |
Re: mehrere Thread-Instanzen
nix Glaskugel. Kaffeesatz, Vogelflug, Innereien, Feuer, Knochenwerfen, da gibts viele nette Alternativen.
|
Re: mehrere Thread-Instanzen
@Whookie: Die beiden Threads werden schon richtig erzeugt, dass kann ich nachvollziehen, da ich einen überlagerten Constructor hab und der auch 2x aufgerufen wird. Die Threads sollten auch nicht einfach so beendet werden. Der Constructor und das Execute des Threads:
Delphi-Quellcode:
@OlafSt: Der Com-Port wird nicht beim kreieren des Threads geöffnet, daran kann es also nicht liegen.
constructor devThread.create(arrid:integer);
begin inherited create(False); myid := arrid; mycport := TComPort.Create(nil); mycport.Port := devicearr[myid].SETTINGS.PORT; mycport.BaudRate := devicearr[myid].SETTINGS.BAUD; mycport.Parity.Bits := devicearr[myid].SETTINGS.PARITY; mycport.StopBits := devicearr[myid].SETTINGS.STOP; mycport.DataBits := devicearr[myid].SETTINGS.DATA; mycport.FlowControl.FlowControl := devicearr[myid].SETTINGS.FLOW; mycport.Events := [evRXChar,evRXFlag]; mycport.OnAfterOpen := afteropen; mycport.OnRxChar := reseive; end; procedure devThread.Execute; begin { Thread-Code hier einfügen } while not terminated do begin mystate := devicearr[myid].STATE; sleep(1); end; end; Wie gesagt: Der constructor Create wird ordentlich gestartet nur wird immer das Execute der zuletzt kreierten Threads durchlaufen. Das ist alles sehr seltsam ... :pale: |
Re: mehrere Thread-Instanzen
Unabhängig davon, das es irgendwie nicht richtig funktioniert, würde ich niemals einen Thread so schreiben, das er endlos pollt. Windows ist ein ereignisgesteuertes System, Du solltest also eventorientiert arbeiten.
Erzeuge doch einfach deine TComPort-Instanzen für jeden Port, werte im OnStatechanged, OnDataReceived (oder wie die Ereignisse heißen) die Statii (Statusse?) aus und empfange die Daten in OnDataReceived. Da der 'Sender' (also hier die TComPort-Instanz) mitgeschickt wird, weisst Du genau, auf welchem Port etwas anliegt. So wird das System unnötig blockiert, weil es ja ständig einen Status abfragt. Das war früher in DOS-Zeiten usus, aber heute sagt uns doch Windows, wer, ob, wann und was am COM-Port rumzuppelt. Du kannst Dir das auch vermutlich mit einem 'WaitForMultipleObjects' selbst basteln, aber es ist schon 5,6 Jahre her, das ich mich mit COM rumschlagen musste... |
Re: mehrere Thread-Instanzen
Also wie schon oben gesagt, das pollen im Execute ist sicher nicht die feine englische Art. Mit
![]() ![]()
Delphi-Quellcode:
Das ist ein Auszug aus meiner eigenen Komponente, das Schreiben besorgt ein eigener WriteThread - für alle Comms gemeinsam.
procedure TCommThread.Execute;
var Handles: Array[0..3] Of THandle; dummy: DWord; begin Handles[0] := hTerminateEvent; Handles[1] := iOverlapped.hEvent; Handles[2] := hClosePortEvent; Handles[3] := hOpenPortEvent; repeat WaitCommEvent(FCommHandle, FEvtMask, @iOverlapped); // Init Wait (returnes immediately, because of overlapped event) Case WaitForMultipleObjects(4, @Handles, FALSE, INFINITE) Of // Wait for an event to occur WAIT_OBJECT_0+0: Begin Terminate; Break; End; // Zeichen empfangen WAIT_OBJECT_0+1: Begin If GetOverlappedResult(FCommHandle, iOverlapped, dummy, FALSE) Then Begin If ClearCommError(FCommHandle, fErrorMask, @fCT) Then Begin If (fEvtMask=EV_RXCHAR) And (fCT.cbInQue=0) Then Continue; // restart loop!! If Assigned(FOnThreadEvent) Then Synchronize(DoOnThreadEvent); End Else GetLastError; // returns 6 (INVALID_HANDLE) End Else Begin dummy := GetLastError; // reset error ResetEvent(iOverlapped.hEvent); // new 30.6.2003 (reset false event) End; End; // Schnittstelle schließen WAIT_OBJECT_0+2: Begin CloseHandle(fCommHandle); fCommHandle := INVALID_HANDLE_VALUE; ResetEvent(hClosePortEvent); End; // Schnittstelle öffnen WAIT_OBJECT_0+3: Begin InitializePort; ResetEvent(hOpenPortEvent); End; else Begin // Should never happen (DON'T EXIT) End; End; until Terminated; CloseHandle(FCommHandle); fCommHandle := INVALID_HANDLE_VALUE; CloseHandle(iOverlapped.hEvent); CloseHandle(hTerminateEvent); CloseHandle(hClosePortEvent); CloseHandle(hOpenPortEvent); end; |
Re: mehrere Thread-Instanzen
Wie wäre es mit WorkerThreads?
![]() |
Re: mehrere Thread-Instanzen
:stupid: Ich,
![]() Ich muss aber nochmal betonen, das das unnötig ist. Wie Whookie schon gezeigt hat, sollte das nur mit einem einzigen Thread ablaufen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:04 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz