Ich habe dieses Problem in vielen bekannten Foren angesprochen, aber keine konkrete Antwort erhalten. Meine Anwendung verwendet serielle Kommunikation, um mit externen Systemen zu kommunizieren, die jeweils ihr eigenes Schnittstellenprotokoll haben. Die Daten, die von den Systemen empfangen werden, werden auf einem GUI in Qt 4.2.1 gemacht angezeigt.
Die Struktur der Anwendung ist so, dass
-
Beim Start der Anwendung erscheint eine Anmeldeseite mit einer Auswahl von vier Modulen. Diese ist als eine Maindisplay Klasse implementiert. Jedes der vier Module ist eine Klasse für sich selbst. Das betreffende Modul ist hier die Klasse action, die für das Sammeln und Anzeigen von Daten aus verschiedenen Systemen zuständig ist.
-
Benutzerauthentifizierung bringt ihn/sie auf den Aktionsbildschirm. Der Konstruktor des Aktionsbildschirms Klasse wird ausgeführt und abgesehen von banalen Initialisierung startet er die einzelnen System-Threads, die als als Singleton implementiert sind.
Jedes Systemprotokoll ist als Singleton-Thread in der Form implementiert:
class SensorProtocol:public QThread {
static SensorProtocol* s_instance;
SensorProtocol(){}
SensorProtocol(const SensorProtocol&);
operator=(const SensorProtocol&);
public:
static SensorProtocol* getInstance();
//miscellaneous system related data to be used for
// data acquisition and processing
};
In der Implementierungsdatei *.cpp:
SensorProtocol* SensorProtocol::s_instance=0;
SensorProtocol* SensorProtocol::getInstance()
{
//DOUBLE CHECKED LOCKING PATTERN I have used singletons
// without this overrated pattern also but just fyi
if(!s_instance)
{
mutex.lock();
if(!s_instance)
s_instance=new SensorProtocol();
mutex.unlock();
}
}
Struktur der Lauffunktion
while(!mStop)
{
mutex.lock()
while(!WaitCondition.wait(&mutex,5)
{
if(mStop)
return;
}
//code to read from port when data becomes available
// and process it and store in variables
mutex.unlock();
}
In der Aktionsbildschirmklasse habe ich einen InputSignalHandler mit sigaction und saio definiert. Dies ist ein Funktionszeiger, der aktiviert wird, sobald Daten an einer der seriellen Schnittstellen ankommen.
Es handelt sich um eine globale Funktion (wir können sie nicht ändern, da sie Linux-spezifisch ist), die lediglich dazu dient, die Dateideskriptoren der seriellen Schnittstelle, an der Daten angekommen sind, mit den fd's der Sensorsysteme zu vergleichen. Wenn eine Übereinstimmung gefunden wird, wird WaitCondition.wakeOne auf diesem Thread aufgerufen, der dann aus dem Wartezustand herauskommt und die Daten liest und verarbeitet.
In der Aktionsbildschirmklasse werden die einzelnen Threads gestartet als SensorProtocol::getInstance()->start()
.
Jedes Systemprotokoll hat eine Rahmenrate, mit der es Daten sendet. Auf der Grundlage dieser Tatsache haben wir im Aktionsbildschirm Aktualisierungszeitgeber eingerichtet, die bei der Aktualisierungsrate der Protokolle ablaufen. Wenn diese Timer ablaufen, wird die Funktion UpdateSensorProtocol() des Aktionsbildschirms aufgerufen
connect(&timer, SIGNAL(timeout), this,SLOT(UpdateSensorProtocol()));
Dies packt eine Instanz von Sensor Singleton als
SensorProtocol* pSingleton=SensorProtocol::getInstance();
if(pSingleton->mUpdate)
{
//update data on action screen GUI
pSingleton->mUpdate=false; //NOTE : this variable is set to
// true in the singleton thread
// while one frame is processed completely
}
Für alle Verwendungen der Singleton-Instanz SensorProtocol::getInstance()
verwendet wird. In Anbetracht des obigen Szenarios bleibt eines meiner Protokolle hängen, egal welche Änderungen ich vornehme.
Das Problem tritt auf, wenn Daten mit UpdateSensorProtocol() angezeigt werden. ShowSensorData()
Funktion in der UpdateSensorProtocol()
funktioniert es gut. Aber sonst bleibt es hängen und die GUI friert ein. Irgendwelche Vorschläge!
Auch, da der Haupt-Thread die laufende Instanz von Singleton ergreift, ist es wirklich Multithreading, weil wir im Wesentlichen mUpdate in Singleton selbst ändern, obwohl von Aktion-Bildschirm.
Ich bin in dieser Hinsicht verwirrt.
Kann jemand einen alternativen Entwurf zu dem vorschlagen, was ich jetzt mache?
Vielen Dank im Voraus