2013-11-01 87 views
2

我用std :: thread和C++ 11試驗了一下,我遇到了奇怪的行爲。 請看看下面的代碼:C++ 11 std ::線程奇怪的行爲

#include <cstdlib> 
#include <thread> 
#include <vector> 
#include <iostream> 

void thread_sum_up(const size_t n, size_t& count) { 
    size_t i; 
    for (i = 0; i < n; ++i); 
    count = i; 
} 

class A { 
public: 
    A(const size_t x) : x_(x) {} 

    size_t sum_up(const size_t num_threads) const { 
    size_t i; 
    std::vector<std::thread> threads; 
    std::vector<size_t> data_vector; 
    for (i = 0; i < num_threads; ++i) { 
     data_vector.push_back(0); 
     threads.push_back(std::thread(thread_sum_up, x_, std::ref(data_vector[i]))); 
    } 

    std::cout << "Threads started ...\n"; 

    for (i = 0; i < num_threads; ++i) 
     threads[i].join(); 

    size_t sum = 0; 
    for (i = 0; i < num_threads; ++i) 
     sum += data_vector[i]; 
    return sum; 
    } 

private: 
    const size_t x_; 
}; 

int main(int argc, char* argv[]) { 
    const size_t x = atoi(argv[1]); 
    const size_t num_threads = atoi(argv[2]); 
    A a(x); 
    std::cout << a.sum_up(num_threads) << std::endl; 
    return 0; 
} 

這裏的主要想法是,我要指定一個數字裏面做獨立的計算(在這種情況下,簡單的增量)的線程。 所有線程完成後,結果應合併以獲得總體結果。

只是爲了澄清:這只是爲了測試目的,爲了讓我明白C++ 11線程是如何工作的。

但是,使用命令

g++ -o threads threads.cpp -pthread -O0 -std=c++0x 

在Ubuntu的盒子編譯此代碼時,我得到很奇怪的現象,當我執行的結果二進制。 例如:

$ ./threads 1000 4 
Threads started ... 
Segmentation fault (core dumped) 

(應產生的輸出:4000)

$ ./threads 100000 4 
Threads started ... 
200000 

(應產生的輸出:400000)

有誰有一個想法是怎麼回事呢?

預先感謝您!

回答

2

您的代碼有很多問題(見甚至thread_sum_up約2-3錯誤),但我發現掠你的代碼的主要錯誤是在這裏:

看,當你push_back成向量(我正在談論data_vector),它可以將以前的所有數據移到內存中。但是,然後你的地址(參考)爲您的線程單元格,然後再次推回(使以前的引用無效)

這將導致您崩潰。

一個簡單的修復 - 創建它後立即添加data_vector.reserve(num_threads);

編輯按您的要求 - 在thread_sum_up

void thread_sum_up(const size_t n, size_t& count) { 
    size_t i; 
    for (i = 0; i < n; ++i); // see that last ';' there? means this loop is empty. it shouldn't be there 
    count = i; // You're just setting count to be i. why do that in a loop? Did you mean +=? 
} 
+1

一些錯誤非常感謝您的回答,您的建議解決了這一問題。但是,請你也可以告訴thread_sum_up中的其他錯誤(只是爲了讓我知道我做錯了什麼)? –

+0

我一定會對'thread_sum_up'中的2-3個bug感興趣。除非你以某種方式解釋任何優化器將它變成'count = n;'作爲錯誤的事實。 – Angew

+0

@SvenHager編輯了'thread_sum_up'錯誤的帖子,我找到了 – rabensky

1

您的崩潰的原因可能是std :: ref(data_vector [i])被data_vector中的下一個push_back無效。由於您知道線程的數量,因此在開始產生線程以防止引用失效之前,先執行data_vector.reserve(num_threads)。

1

在調用push_back調用矢量時,它很可能必須重新分配存儲空間,導致對包含值的引用無效。這會導致線程寫入未分配的內存,這是未定義的行爲。

您的選擇是預先分配您需要的尺寸(vector::reserve是一種選擇)或選擇不同的容器。