2012-06-27 36 views
0

在多線程應用程序,是msleep()是否給其他線程賦予循環?

while (result->Status == Result::InProgress) Sleep(50); 
//process results 

while (result->Status == Result::InProgress); 
//process results 

更好? 因此,我問第一種方法會在等待結果而不是不斷旋轉的同時對其他線程有禮貌嗎?我正在等待的操作通常需要大約1-2秒,並且處於不同的線程中。

回答

1

它更好,但不是太多。

只要result->Status不是volatile,編譯器允許減少

while(result->Status == Result::InProgress); 

if(result->Status == Result::InProgress) for(;;) ; 

作爲條件不循環內改變。

調用外部(並且因此隱含地volatile)函數Sleep改變這一點,因爲這可能會修改result結構,除非編譯器知道,Sleep從未修改數據。因此,根據編譯器的不同,第二種實現不太可能進入無限循環。

也不保證對result->Status的訪問是原子性的。對於特定的內存佈局和處理器體系結構,讀寫此變量可能由多個步驟組成,這意味着調度程序可能決定介入中間。

由於此刻你所溝通的只是一個簡單的yes/no,而接收線程也應該等待一個否定的回覆,最好的方法是使用你的OS提供的適當的線程同步原語來實現這種效果。這有一個好處,就是當條件改變時你的線程立即被喚醒,並且它在此期間不使用CPU,因爲操作系統知道你的線程正在等待什麼。

在Windows上,使用CreateEvent和co。使用事件對象進行通信;在Unix上,使用一個pthread_cond_t對象。

1

是的,睡眠和變種放棄了處理器。其他線程可以接管。但有更好的方法等待其他線程。

請勿使用空循環。

2

我會建議使用信號而不是輪詢。如果你喜歡主動等待,睡眠比持續評估循環條件更好。

1

這也取決於您的操作系統調度策略。例如,Linux默認使用CFS schedular,因此它會公平地將處理器分配給所有任務。但是,如果您將此線程作爲帶有FIFO策略的實時線程,那麼沒有睡眠的代碼將永遠不會讓處理器重新分配,除非有更高優先級的線程來到,否則相同優先級或更低的線程將永遠不會被調度,直到您從循環中斷開。如果應用SCHED_RR,那麼具有相同優先級和更高優先級的進程將被調度但不會降低。