Thread mehrmals starten
-
Hallo,
ich möchter gerne eine Klasse die einen Thread startet mehrmals aufrufen.
der/die Threads sollen COM1 und COM2 abfragen. Leider wird nur der zuletzt aufgerufene Thread ausgeführt.Hat jemand eine Lösung für mich? ich benutzt C++Bulder XE
Danke
-
Leider musste ich aufgrund der Wirtschaftskrise meine Kristallkugel versetzen, bitte zeig´ doch mal etwas Code, damit man dein Problem erkennen kann.
-
Hallo
Für mehrere gleichzeitig laufende Threads must du natürlich auch entsprechend viele Thread-Instanzen haben. Und du must darauf achten das sich die einzelnen Threads nicht in die Quere kommen, beim Zugriff auf Daten die nicht Member der Thread-Klasse (bzw. deiner von TThread abgeleiteten Klasse) selbst sind.
Aber wie schon DocShoe gesagt hat : Konkrete Hinwesie können wir nur bei mehr Details deinerseits geben.
bis bald
akari
-
ich habe nur eine ganz einfache Klasse erstellt
ich rufe 2 mal eine Instanz der klasse auf übergebe nur den COM port
und als thread habe ich das, vom C++Builder, vorgegeben Thread Objekt erzeugt.ich habe mir mal mit der Thread ID mal beide Threads mit der systemzeit ( Time() ) anzeigen lassen. Beide Threads laufen auch Paralel aber ich kann immer nur von dem zuletzt gestartenen Thread den Seriell Port abfragen.
vielleicht hilft euch das
KLasse aus der aufgerufen wird
void __fastcall TForm1::Button1Click(TObject *Sender) { TSerialClass *SerialClass = new TSerialClass(NULL); SerialClass->InitSerialPort("COM1"); TSerialClass *SerialClass2 = new TSerialClass(NULL); SerialClass2->InitSerialPort("COM2"); }
Klasse den Den Tread Startet und den Serialport öffnet
#include <vcl.h> #pragma hdrstop #include "SerialPort.h" #include "serial.h" #include "main.h" HANDLE hComm = NULL; COMMTIMEOUTS ctmoNew = {0}, ctmoOld; //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TSerialClass *SerialClass; extern TForm1 * Form1; TSerial *SerialPort; //--------------------------------------------------------------------------- __fastcall TSerialClass::TSerialClass(TComponent* Owner) : TDataModule(Owner) { } //--------------------------------------------------------------------------- void __fastcall TSerialClass::InitSerialPort(String Port) { DCB dcbCommPort; COMMTIMEOUTS sTo; hComm = CreateFile( Port.c_str(), GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0); if(hComm == INVALID_HANDLE_VALUE) { TaskMessageDlg("Fehler", "Port nicht bereit!", mtError, TMsgDlgButtons() << mbOK , 0); } else { Form1->Caption = "Verbindung hergestellt " + Port; } GetCommTimeouts(hComm,&ctmoOld); ctmoNew.ReadTotalTimeoutConstant = 100; ctmoNew.ReadTotalTimeoutMultiplier = 0; SetCommTimeouts(hComm, &ctmoNew); dcbCommPort.DCBlength = sizeof(DCB); GetCommState(hComm, &dcbCommPort); dcbCommPort.BaudRate = 1200; dcbCommPort.ByteSize = 8; dcbCommPort.Parity = 0; dcbCommPort.StopBits = 0; SetCommState(hComm, &dcbCommPort); TSerial *SerialPort = new TSerial(false); } // ---------------------------------------------------------------------------
Der Thread
#include <vcl.h> #pragma hdrstop #include "serial.h" #include "main.h" #include "SerialPort.h" #pragma package(smart_init) extern HANDLE hComm; wchar_t InBuff[100]; extern TSerialClass *SerialClass; //--------------------------------------------------------------------------- __fastcall TSerial::TSerial(bool CreateSuspended) : TThread(CreateSuspended) { } //--------------------------------------------------------------------------- void __fastcall TSerial::Execute() { DWORD dwBytesRead; FreeOnTerminate = true; while(1) { Form1->Memo1->Lines->Add((String) CurrentThread->ThreadID + ": " + TimeToStr(Time())); //Das geht auch und die zeit wird mit beiden ThreadID's weitergezält if(Terminated) return; ReadFile(hComm, InBuff, 100, &dwBytesRead, NULL); if(dwBytesRead) { InBuff[dwBytesRead] = 0; Synchronize(DisplayIt); } } } //--------------------------------------------------------------------------- void __fastcall TSerial::DisplayIt(void) { //Anzeige } //---------------------------------------------------------------------------
-
Das scheitert schon daran, dass du eine globale Variable (hComm) für mehrere Objekte benutzt. Insgesamt ist dein Code etwas unübersichtlich, da du deine Variablen als globale Variablen hältst statt sie als member der Klasse zu machen, zu der sie eigentlich gehören. Mein Rat: Mach hComm zu einem Member der Klasse TSerialClass, spendier ihr noch eine Read() Methode und übergib deiner Threadklasse eine Instanz auf TSerialClass. In der Execute Methode kann der Thread dann durch die public Read() Methode Daten lesen.
-
Danke DocShoe so wie du mir das beschrieben hast hab ich das schon verstanden
aber wie setzte ich das um ich stehe grad irgendwie auf dem schlauch
-
Was ist daran so schwierig?
-
ich weiß grad nicht wie ichs machen soll :p
-
ich weiß grad nicht wie ichs machen soll :p
erst 1, danach 2.. nach 2 kommt die 3 und zum schluss die 4.
DocShoe schrieb:
Das scheitert schon daran, dass du eine globale Variable (hComm) für mehrere Objekte benutzt. Insgesamt ist dein Code etwas unübersichtlich, da du deine Variablen als globale Variablen hältst statt sie als member der Klasse zu machen, zu der sie eigentlich gehören. Mein Rat: **(1)**Mach hComm zu einem Member der Klasse TSerialClass, **(2)**spendier ihr noch eine Read() Methode und **(3)**übergib deiner Threadklasse eine Instanz auf TSerialClass. **(4)**In der Execute Methode kann der Thread dann durch die public Read() Methode Daten lesen.
-
und wie übergebe ich von der Threadklasse eine Instanz auf TSerialClass?
-
im privaten bereich, einen Pointer auf TSerialClass definieren und den Konstruktor so abändern, dass du einen Pointer auf TSerialClass übergeben kannst.
-
ich weiß nicht wie ich das machen soll.
ein kurzer quelltext wäre echt hilfreich.Danke schonmal.