2017-03-09 97 views
1

我想從線程修改一些字符串(每個線程都有自己的字符串),但所有字符串都存儲在一個向量中,因爲我需要能夠在線程完成它們的事情後訪問它們。如何從線程修改字符串?

我沒有用在C++的線程,因此,如果這是做一件可怕的事情,所有的建議表示歡迎:)

基本上唯一的程序不會是現在:

  • 創造一些螺紋
  • 發送一個字符串和一個ID給每個線程
  • 線程函數修改字符串的ID添加到它
  • 結束

這給出了一個段錯誤:(

這只是一個不錯的辦法?我還能怎麼做?

static const int cores = 8; 

void bmh_t(std::string & resr, int tid){ 
    resr.append(std::to_string(tid)); 
    resr.append(","); 
    return; 
}   

std::vector<std::string> parbmh(std::string text, std::string pat){ 

    std::vector<std::string> distlists; 
    std::thread t[cores]; 
    //Launch a group of threads 
    for (int i = 0; i < cores; ++i) { 
     distlists.push_back(" "); 
     t[i] = std::thread(bmh_t,std::ref(distlists[i]), i); 
    } 

    for (int i = 0; i < cores; ++i) { 
     t[i].join(); 
    } 

    return distlists; 
} 
+5

預分配的載體。 Pushback可以在大多數標準庫中調整並移動向量元素,這不是線程安全的。一旦建立了矢量大小,它就是線程安全的。 – doug

+0

偏題:看看'std :: future'。 – user4581301

回答

4

你的基本方法很好。編寫並行代碼時需要考慮的主要事情是線程之間共享的任何數據都以安全的方式完成。因爲你的算法爲每個線程使用不同的字符串,所以這是一個好方法。

您看到崩潰的原因是因爲您在向每個線程提供存儲在向量中的數據的引用之後調用了字符串向量的push_back。這是一個問題,因爲當尺寸達到其容量時,push_back需要增加矢量。這種增長會使您分配給每個線程的引用無效,導致它們寫入釋放的內存。

該修復非常簡單:只需確保您的向量不需要增長即可。這可以通過指定初始元素數量的構造函數參數來完成;調用reserve();或者調用resize()。

下面是不會崩潰的實現:

static const int cores = 8; 

void bmh_t(std::string & resr, int tid){ 
    resr.append(std::to_string(tid)); 
    resr.append(","); 
    return; 
} 

std::vector<std::string> parbmh(){ 

    std::vector<std::string> distlists; 
    std::thread t[cores]; 
    distlists.reserve(cores); 

    //Launch a group of threads 
    for (int i = 0; i < cores; ++i) { 
     distlists.push_back(" "); 
     t[i] = std::thread(bmh_t, std::ref(distlists[i]), i); 
    } 

    for (int i = 0; i < cores; ++i) { 
     t[i].join(); 
    } 

    return distlists; 
} 
+1

考慮你爲什麼也使用矢量。例如,您可以使用一組字符串,因爲您需要預先設置矢量。 – Donnie

+0

可能值得注意的是,使用當前代碼來分配'std :: vector :: resize()'將不起作用,因爲'push_back'。 – Galik

+0

@Donnie數組的大小固定,除非你動態地分配它們,然後你可以使用一個向量(它也會做同樣的事情)。也返回一個數組是有問題的。 – Galik

1

串的矢量被破壞之前的螺紋可以在包含字符串行事。你會想要返回之前的線程join,以便字符串的矢量不被破壞。

+0

「被破壞」?最初的副本,也許,但有'返回distlists;',如果OP想要在'parbmh'返回後使用該向量呢? 我在想這裏可能有不好的設計,但是有足夠的信息嗎? – Aaron

+0

@Aaron是的,有足夠的信息,答案是正確的。 –

+0

@πάνταῥεῖ所以,你知道OP是不是正在返回distlists,因爲他計劃在當前線程的其他地方使用它,並且OP並不打算讓當前線程在生成線程執行時運行?也許他是這個意思。從你的角度來看,我認爲這更有意義。沒有明確說明,但我想這是暗示的。 – Aaron