2016-08-03 45 views
0

你好,我是C++多線程新手。我正在使用C++ 11中提供的線程類,以便在不同的線程中運行函數,但不知何故,從函數獲得的輸出非常尷尬。這可能是因爲不同的線程可能試圖同時執行相同的變量,從而導致衝突。請建議我應該如何修改我的代碼,以便我可以得到正確的輸出。我發佈了一個我正在嘗試做的示例代碼。這不是原始代碼,但它只是顯示我的原始代碼的流程,因爲我的原始代碼太長而無法發佈,但問題在兩種情況下都保持不變。在不同線程中運行的函數會產生奇怪的輸出

#include<iostream> 
    #include<thread>  

    using namespace std; 

    typedef struct { 
     int thread_id; 
     char *message; 
    }threadData; 

    int display(threadData *tData){ 
     threadData *my_data; 
     my_data = (threadData *) tData; 

     cout << "Thread ID: " << my_data -> thread_id << endl; 
     cout << "Message: " << my_data -> message << endl; 

     return 0; 
    } 

    int main(){ 

     threadData *data; 

     data = (threadData *)malloc(sizeof(threadData)); 
     data->thread_id = 12; 
     data->message = "This is the message"; 
     for (int i = 0; i<10; i++) 
     { 
      std::thread t1(display, data);  
      t1.detach(); 
     } 
     return 0; 
    } 

輸出:

Thread ID: 12 
    Message: This is the messageThread ID: 
    12 
    Message: This is the message 
    Thread ID: 12 
    Message: This is the message 
    Thread ID: 12 
    Message: This is the message 
    Thread ID: 12 
    Message: This is the message 
+1

您想了解鎖定和內存模型。認真:這是一個非常廣泛的話題;你不應該去「舉例」;但「按概念」。含義:研究這個話題;例如通過在網上搜索「C++線程鎖定示例」。我的意思是:是的,當人們向你解釋一些東西的時候很好。但這些東西被記錄了數十億次;而不是寫出這個問題,你會花費更少的時間來搜索網絡。請注意:這仍然是一個有效的問題,所以沒有downvote或近距離投票,但仍然... – GhostCat

+1

確實,閱讀有關鎖定和一般線程概念。另外,'malloc'和'C++'? 'typedef struct'?您可能也想梳理一下C++。 –

回答

0

由於線程不guaruntee先運行, 你需要保護訪問共享資源。 最簡單的方法是通過互斥鎖。

std::mutex g_i_mutex; // protects g_i 

typedef struct { 
    int thread_id; 
    string message; 
}threadData; 

int display(threadData *tData) 
{ 
std::lock_guard<std::mutex> lock(g_i_mutex); 
threadData *my_data; 
my_data = (threadData *) tData; 

cout << "Thread ID: " << my_data -> thread_id << endl; 
cout << "Message: " << my_data -> message << endl; 

return 0; 

}

輸出:

線程ID:12 消息:這是消息 線程ID:12 消息:這是消息 線程ID:12 消息:這是信息 螺紋編號:12 信息:這是信息

我建議你多閱讀一些關於線程概念。背後的概念並不簡單,只是獲得一個現成的解決方案從長遠來看不會對您有所幫助。

2

我讀的是for循環預期運行10次,但它只運行了4次,原因是因爲在主函數中沒有等待所有線程完成,所以主進程退出之前線程有機會運行。 '主'需要睡一會兒等待所有線程完成他們的工作。

而我在這裏沒有看到競爭條件,因爲所有線程只是讀取,沒有人寫入threadData。