2012-10-20 18 views
3

在C/C++中如何讓線程(POSIX pthreads/Windows線程)爲我提供一個安全的方法,以將進度傳遞迴執行進度的主線程或我已決定用線程執行的工作。在C++中向主線程報告線程進度

是否可以按百分比報告進度?

+1

哪個操作系統?什麼類型的應用程序?如果它是一個GUI應用程序,只需使用PostMessage即可。 – enhzflep

回答

4

解決這個問題的最好方法就是使用C++原子。聲明在一些可見的不夠到位:

std::atomic<int> my_thread_progress(0); 

在簡單的情況下,這應該是一個靜態變量,在更復雜的地方,這應該是一個管理線程或類似的東西某個對象的數據字段。

在很多平臺上,這將會有點偏執狂,因爲幾乎在任何地方對整數的讀寫操作都是原子的。使用原子的位仍然是因爲:

  1. 您將保證這可以在任何平臺上正常工作,即使在16位CPU或任何不尋常的硬件上;
  2. 您的代碼將更易於閱讀。讀者將立即看到這是共享變量,而不會發表任何評論。一旦它將用load/store方法進行更新,將更容易捕捉正在發生的事情。

EDIT

64和IA-32架構軟件開發人員手冊 結合卷:1,2A,2B,2C,3A,3B和3C(http://download.intel.com/products/processor/manual/325462.pdf

卷3A :8.1.1保證的原子操作

Intel486處理器(以及更新的處理器)確保以下基本存儲器操作始終以原子方式執行:

  • 讀取或寫入字節
  • 讀取或寫入一個16位的邊界
  • 閱讀上對齊的字或寫一個32位的邊界
+0

嗨基里爾,我需要一個機制,從線程發送信息說線程A通過消息傳遞系統主線程 – Laavaa

+1

如果這是簡單的狀態數據,聲明幾個原子變量。否則,請使用STL隊列並使用STL互斥鎖保護對此隊列的訪問。 –

3

我在對準一個雙將假設一個非常簡單的主線程和一個函數。我推薦的是每次啓動線程時傳遞一個指向原子的指針(如上面Kirill所建議的)。在這裏假設C++ 11。

using namespace std; 

void threadedFunction(atomic<int>* progress) 
{ 
    for(int i = 0; i < 100; i++) 
    { 
     progress->store(i); // updates the variable safely 
     chrono::milliseconds dura(2000); 
     this_thread::sleep_for(dura); // Sleeps for a bit 
    } 
    return; 
} 

int main(int argc, char** argv) 
{ 
    // Make and launch 10 threads 
    vector<atomic<int>> atomics; 
    vector<thread> threads; 
    for(int i = 0; i < 10; i++) 
    { 
     atomics.emplace_back(0); 
     threads.emplace_back(threadedFunction, &atomics[i]); 
    } 

    // Monitor the threads down here 
    // use atomics[n].load() to get the value from the atomics 
    return 0; 
} 

我覺得那會做你想做的。我省略了輪詢線程,但你明白了。我傳遞了一個對象,主線程和子線程都知道它們都可以更新和/或輪詢結果(在這種情況下爲atomic<int>變量)。如果您不是完整的C++ 11線程/原子支持編譯器,請使用您的平臺確定的任何內容,但總有辦法將變量(至少爲void*)傳遞給線程函數。這就是你如何通過非靜態信息來回傳遞信息。

+1

應該指出的是,指向矢量元素的指針並不安全。您調整'atomics'大小的事實可能會使傳遞給線程的指針無效。 – nwn

+1

你說得對。您必須首先保留所有空間,否則這些指針可能會失效。接得好。 LinkedList <>在這裏是更好的選擇,因爲擴展它並不會使現有元素無效。 –