2017-05-13 4 views
0

Ich habe eine GTK-Anwendung, wo ich einige Aufgaben parallel ausführen müssen. Die Anwendung empfängt Daten von einer seriellen Schnittstelle und muss dann abhängig von den Daten Text auf dem Etikett anzeigen und Audio abspielen. Ich verwende eine ereignisbasierte serielle Kommunikation, die ein Flag hoch setzt, wenn die Daten empfangen werden.Multitasking in GTK-Anwendung

In der Hauptschleife habe ich 3 Threads erstellt, die ich infinitely laufen lasse.

Thread1 to read serial data 
Thread2 to display data on gtk label 
Thread3 to play audio 

Thread1 wird aktiviert, wenn das Signal vom seriellen Port-Ereignis empfangen wird. Nach dem Lesen der Daten wird ein Flag high gesetzt, das dann Thread2 aktiviert. Thread2 dekodiert dann die seriellen Daten und zeigt ihre Informationen auf dem Etikett an. Es setzt dann ein anderes Flag high, welches das Thread3 aktiviert und dann Thread3 eine Audiodatei wiedergibt.

Ich muss Thread2 und Thread3 parallel ausführen. Damit der Text, der auf dem Etikett und im Audio angezeigt wird, gleichzeitig erfolgen soll. Zur Zeit mache ich etwas wie unten:

Thread2 
{ 
    while(1) 
    { 
    if(serialData == TRUE) 
    { 
     //decode the serial data and display it 
     startAudio = TRUE //Indicate Thread3 to play audio 
     serialData = FALSE 
    } 
    } 
} 

Thread3 
{ 
    while(1) 
    { 
    if(startAudio == TRUE) 
    { 
     //play audio 
     startAudio = FALSE 
    } 
    } 
} 

Zu aktueller Situation, ich habe nicht viel serielle Daten zu dekodieren, so Text angezeigt und Audio beiden Blicke synchronisiert. Aber wenn die Daten groß sind, dann denke ich, dass beide nicht synchronisiert werden. Gibt es eine Möglichkeit, diese Aufgabe parallel auszuführen?

+5

Wenn Sie asynchrone Bibliotheken (wie Gio, Gstreamer) verwenden, sollte es keinen Grund geben, Threads für die von Ihnen erwähnten Aufgaben zu verwenden. Ich sage nicht, dass man sie nicht benutzen kann, aber wenn man Threads meiden kann, ist das normalerweise eine gute Idee. – jku

Antwort

0

Sie müssen nur startAudio = TRUE; in Thread 1 anstelle von Thread 2 festlegen, zum Beispiel, nachdem Sie serialData = TRUE; festgelegt haben.

Eine andere Lösung ist startAudio = TRUE; in Thread 2, aber vor der Decodierung der Daten, nicht nach.

Wenn Sie möchten, dass die Anzeige von Daten und nicht die Dekodierung mit dem Ton synchronisiert wird, dann scheint das, was Sie getan haben, die beste Lösung zu sein, denn ich denke, sobald die Daten entschlüsselt sind, dauert es nicht viel Zeit, um es anzuzeigen. Sie können jedoch versuchen, startAudio = TRUE; vor der Anzeige der Daten zu setzen, aber nach der Dekodierung wird die Anzeige der Daten und die Wiedergabe des Tons parallel erfolgen.

Aber wenn die Anzeige der Daten kann eine Menge Zeit dauern, dann die einzige Art und Weise zu sehen, dass die Anzeige und der Ton synchronisiert zu sein, ist es, den Ton gerade nach der Anzeige zu spielen, so dass Sie brauchen um startAudio = TRUE; direkt nach dem GTK-Aufruf festzulegen, der das Label aktualisiert.

Eine andere Möglichkeit zum Synchronisieren von Threads besteht in der Verwendung von Bedingungen. Sie ist komplexer als Ihre Implementierung. Wenn ein Thread jedoch auf eine Bedingung wartet, verwendet sie wesentlich weniger CPU als zur Variablenprüfung in Ihrer Implementierung.

Verwandte Themen