2016-05-16 45 views
1

我正在寫兩個相互合作的應用程序。一個是C++,另一個是C#。由於有流涉及的數據,我使用,在多個地方,這樣的代碼:正在使用多個'while()'循環的不良做法?

while (true) 
{ 
//copy streamed data to other places 

} 

我注意到,這些程序都使用了大量的CPU,而成爲反應緩慢。使用這種類型的循環是不好的編程?我應該添加一個:

Sleep(5); 

在每一個?這將有助於使用CPU嗎?

謝謝!

+0

你需要提供一個具體的例子,說明你在循環中做了什麼(不,睡眠(5)幾乎從不會是一個好的解決方案)。 – Evk

+2

你的CPU有100%的使用率。使用它並不壞。 –

+0

我真的只是問一般,因爲我是自學的,而且很容易做壞習慣!這種循環是否可以接受像這樣的全油門?或者我應該暫停/睡在這些循環中? – anti

回答

2

,你可能會發現,代碼更格式

while (true) 
{ 
    //WAIT for streamed data to arrive 
    //READ data from stream 
    //COPY streamed data to other places 

    //BREAK when no more data/program is ending 


} 

這完全是正常的。其他常見的解決方案是

while (boolean_variable_if_program_is_to_keep_running) 
{ 
    //WAIT for streamed data to arrive 
    //READ data from stream 
    //COPY streamed data to other places 

    //when no more data/program is ending 
    // set boolean_variable_if_program_is_to_keep_running = FALSE 


} 
5

一般來說,在代碼中使用Thread.Sleep()也將凍結該線程,所以如果你擔心的是響應你不應該使用它。你應該考慮移動流媒體方式開出主(UI)線程的

另外,你提到的是一些流處理,所以像

while(!stream.EndOfStream) 
{ 
//streaming 
} 

而是用最好的做法不會一些DataReceived事件(如果有的話)

+0

謝謝,我會研究這一點。 – anti

0

這是擴展我上面的評論,但爲了完整起見,我正在粘貼我在這裏寫的評論(並添加到它)。

這種問題的一般解決方案是等待數據的到達並在它到達時對其進行處理(可能會在處理先前到達的數據時緩存新到達的數據)。至於實施的機制 - 嗯,這取決於一個具體的例子。例如,通常在圖形處理應用程序(例如遊戲)中,「遊戲循環」基本上就是您描述的(沒有睡眠)。這在GUI應用程序設計中也遇到過。對於應用程序在處理之前等待事件的設計,請參閱典型的網絡客戶端 - 服務器設計。

至於CPU的放緩,試試下面的代碼來觀察顯著放緩:

while(true); 

while(true) sleep(1); 

究其原因,第一變慢是因爲在每個週期CPU檢查如果循環中的條件評估爲true(即,在這種情況下,如果true == true)。另一方面,在第二個例子中,CPU檢查是否true == true,然後睡1ms,這比檢查true == true所花費的時間長得多,這樣可以釋放CPU來做其他事情。

現在,就您的示例而言,假設處理循環內的數據比檢查true == true需要更多的CPU週期。因此,添加sleep聲明將無濟於事,但只會使情況惡化。

您應該將其留給內核來決定何時中斷您的進程以將CPU週期專用於其他事情。

當然,以上面寫的是一些鹽(特別是最後一段),因爲它描繪的是一個非常簡單的圖片,沒有考慮到您的具體情況,這可能從一個設計相對於另一個設計受益不知道,因爲你沒有提供任何細節)。

1

你真正需要避免的(對於CPU的健康狀況)是讓程序在不使用系統線程等待函數的情況下等待while(true)循環中的數據。

實施例1:

while(true) { 
    if (thereIsSomeDataToStream) { 
     StreamDataFunction(); 
    } 
} 

在這個例子中,如果thereIsSomeDataToStream爲時間假,則CPU將仍然繼續工作100%進行while環路即使沒有數據串流。所以這會浪費CPU並導致你的電腦放慢速度。

實施例2:

while(true) { 
    if (thereIsSomeDataToStream) { 
     StreamDataFunction(); 
    } 
    else { 
     SystemThreadingWaitFunction(); 
    } 
} 

相反,在本例中,當沒有更多的數據要流,則該線程停止一段時間。操作系統將使用這段空閒時間執行其他線程,稍後,系統將喚醒您的線程,該線程將恢復並循環,以便傳輸可能的新數據。那麼沒有太多的CPU浪費,你的電腦將保持響應。

要執行的線程在等待過程中,你可能有幾種可能性:

  • 首先,你可以使用,如你所說,Sleep(t)。這可能會執行 作業:編譯器提供的休眠功能在邏輯上會使用操作系統API 來空閒當前線程。但是在這種情況下,即使有一些數據在 的同時,您也必須等待所有指定的時間。所以如果等待時間太短,CPU就會過度工作,如果時間太長,你的數據流將會滯後。

  • 或者您可以直接使用操作系統API,我會推薦使用該操作系統API。如果您使用的是Microsoft環境,則可以在此處記錄等待方法的大量 :Microsoft wait functions API。例如,您可以創建一個Event對象,其中 將傳入的數據傳送給流。您可以在代碼中或其他程序中的任何位置發出此事件的信號 。在while循環中,您可以調用類似WaitForSingleObject API的函數,該函數將等待信號狀態的事件 。這裏是如何做到這一點的文檔: Using event objects。我不知道Linux或其他系統, ,但我相信你可以在網上找到它。我自己做了幾次, 它不是很難編碼。請享用 ! :)