2017-05-13 56 views
0

我有一個GTK應用程序,我需要並行運行幾個任務。應用程序從串口接收數據,然後根據數據,它必須在標籤上顯示文本並播放音頻。我正在使用基於事件的串行通信,如果收到數據,則會使標誌變爲高電平。gtk應用程序中的多任務

在主循環中,我創建了3個無限制地運行的線程。

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

當從串口事件接收到信號時,線程1被激活。讀取數據後,它將設置一個高位標誌,然後激活Thread2。然後,線程2解碼串行數據並在標籤上顯示其信息。然後它設置另一個高標誌來激活Thread3,然後Thread3播放一個音頻文件。

我需要並行運行Thread2和Thread3。這樣標籤和音頻上顯示的文字應該同時完成。目前,我做這樣的事情如下:

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 
    } 
    } 
} 

在當前形勢下,我沒有太多的串行數據解碼,所以文本顯示和音頻無論是外觀還是同步。但是如果數據很大,那麼我猜他們都不會同步。有什麼辦法可以同時運行這些任務嗎?

+5

如果您使用異步庫(如Gio,Gstreamer),那麼應該沒有理由爲您提到的任務使用線程。我並不是說你不能使用它們,但如果可以的話,避免使用線程通常是一個好主意。 – jku

回答

0

您只需在線程1而不是線程2中設置startAudio = TRUE;,例如在您設置serialData = TRUE;之後。

另一種解決方案是在線程2中設置startAudio = TRUE;,但在解碼數據之前,而不是之後。

如果你想顯示的數據,而不是解碼,與聲音同步,那麼你所做的似乎是最好的解決方案,因爲我認爲一旦數據解碼,它不需要很多時間來顯示它。但是,您可以嘗試在數據顯示之前設置startAudio = TRUE;,但在解碼之後,顯示數據和播放聲音將會並行進行。

但是,如果顯示數據可能需要很長時間,那麼我所看到的使顯示器和聲音似乎同步的唯一方法是在顯示完成後播放聲音,因此您需要在更新標籤的GTK調用之後設置startAudio = TRUE;

線程同步的另一種方式是使用條件,它比實現更復雜,但是當線程正在等待條件時,它比使用實現中的變量檢查更少使用CPU。

相關問題