2013-02-02 55 views
-2

是否有可能在C/C++中「放棄」線程的CPU時間? 例如:放棄CPU時間

void wait(int s) //Low cpu usage 
{ 
int tmp = time(); 
while(tmp + CLOCKS_PER_SEC * s > time()) 
    __AbandonCPUTime(); 
    //Tell cpu to do sth else. 
} 

我試過睡眠(0),但它不工作。

+1

你想達到什麼目的?睡眠一段時間沒有繁忙的循環? – Mario

+2

睡眠(0)的作品,*但*做的很多,必須有一些其他線程準備運行。如果剛纔調用Sleep的線程是唯一被讀取的線程,它將基本上立即被調度/運行。 –

+0

這可能是一個依賴操作系統的行爲。在Win32中,可以使用線程的事件對象等待,但這需要另一個線程來發信號通知事件。不知道這是否有幫助。請參閱http://stackoverflow.com/questions/4170272/does-waitforsingleobject-give-up-a-threads-time-slice – OldProgrammer

回答

4

看看C++ 11的:

#include <thread> 
std::this_thread::yield(); 

你的CPU可以支持_mm_pause()內在(__asm__("pause")海合會),這可能會或可能不會幫助你。

否則,你將着眼於操作系統的特定功能: sched_yield()在Linux並行線程,或SwitchToThread()在Windows

+0

這些技術都不會讓電腦進入閒置狀態。 _mm_pause()只是告訴旋轉更慢。 sched_yield()和SwitchToThread()(以及Sleep(0))不指定線程應該產生多長時間,並且很有可能(特別是在多核系統上)線程將立即調度。 最好的答案是,你應該等待一些東西 - 操作系統有一組豐富的原語,讓你等待事情發生。 如果不成功,請使用非零延遲調用Sleep()(或等價的posix函數),以免旋轉和浪費電力。 –

0

sched_yield()「導致調用線程放棄CPU。」

http://www.kernel.org/doc/man-pages/online/pages/man2/sched_yield.2.html

+1

使用sched_yield是編寫多線程代碼的一種可怕的方式。從sched_yield的文檔「如果調用線程是當時最高優先級列表中唯一的線程,它將在調用sched_yield()後繼續運行。」 這是一種非常常見的情況。如果你在一個循環中調用sched_yield,那麼你只是有一個更復雜的旋轉循環,你正在浪費CPU時間和電力。別。等一下。 https://randomascii.wordpress.com/2012/06/05/in-praise-of-idleness/ –

1

編輯更直接地回答這個問題:你要麼等待的東西(WaitForSingleObject的或GetMessage函數或一些等價),或者如果沒有可以等待睡眠時間的非零毫秒數的事件。

睡眠(0)通常會立即返回,因此您仍然會耗費大量的能量並耗盡用戶電池或提高電費。睡眠(1)仍然是一種黑客攻擊,但它比Sleep(0),_mm_pause(),sched_yield()或SwitchToThread()好很多個數量級。

如果有一個等待運行的,則Windows上的睡眠(0)將產生到具有相同優先級的另一個線程。這很少有用,因爲,尤其是對於線程優先級的動態調整,您永遠無法分辨是否存在具有相同優先級的另一個線程。休眠(0)通常不會切換到更高優先級的線程,因爲該線程(更高優先級)已經在運行。它不會切換到低優先級的線程,因爲它不會。 SwitchToThread有類似的問題。

_mm_pause()告訴CPU閒置幾個週期。這樣可以降低功耗,並且在超線程機器上讓該內核上的其他線程運行得更快。然而這不是你通常應該做的事情。

如果要在n毫秒內喚醒,請調用Sleep(n)。或者,更好的是,等待一個特定的事件。

像sched_yield,Sleep(0)和SwitchToThread這樣的函數通常都是不好的想法,因爲當你想再次運行時它們不會告訴操作系統。

無論您做什麼,都不要等待,即使使用_mm_pause。 http://randomascii.wordpress.com/2012/06/05/in-praise-of-idleness/