2013-02-13 29 views
7

C++ 11'de çok iş parçacıklı kod çalıştıran bir sorunum (segfault) vardı. BuradaC++ 11 std :: vektör eşzamanlı ortamda

#include <vector> 
#include <thread> 

std::vector<int> values; 
int i; 

void values_push_back() 
{ 
    values.push_back(i); 
} 

int main() 
{ 
    while(true) 
    { 
     std::vector<std::thread> threads; 

     for(i=0; i<10; ++i) 
     { 
      std::thread t(values_push_back); 
      threads.push_back(std::move(t)); 
     } 
     for(i=0; i<10; ++i) 
      threads[i].join(); 
    } 

    return 0; 
} 

gdb üzerinde backtrace: http://pastebin.com/5b5TN70c

ki nesi var Burada kodudur?

+0

hmjds yanıta yorumumu görmek ve bl Lütfen yapma indly kodunu kopyala. – inf

cevap

11

Bu, taşınma ile ilgili değildir.

birden fazla parçacığı, aynı vector ancak vector::push_back() üzerinde vector::push_back() yürütme evre değildir. vector'daki değişikliklerin senkronize edilmesi gerekir.

A std::mutexpush_back() çağrıları eşitlemek için kullanılabilir:

std::vector<int> values; 
std::mutex values_mutex; 

void values_push_back() 
{ 
    values_mutex.lock(); 
    values.push_back(i); 
    values_mutex.unlock(); 
} 

Ayrıca değişken i (bu olası bir sonuçtur bir yarış durumu neden olacaktır olup senkronizasyon olmadan parçacıkları arasında paylaşılıyor int yinelenen vector) eklenmiştir. önlemek için konuya bir argüman olarak int değer geçirerek düşünün:

std::vector<int> values; 
std::mutex values_mutex; 

void values_push_back(int i) 
{ 
    values_mutex.lock(); 
    values.push_back(i); 
    values_mutex.unlock(); 
} 

for (int i = 0; i < 10; ++i) 
{ 
    threads.push_back(std::thread(values_push_back, i)); 
} 

for (auto& t: threads) t.join(); 
bamboon push_back() atarsa ​​kilit serbest bırakılır sağlamak için std::lock_guard tercih tarafından yorumladığı gibi

(bu durumda sadece bad_alloc() olabilir ki ama vector değişiklikler kurucular atma var daha karmaşık nesneleri tutmak için eğer) daha önemli hale gelir:

void values_push_back(int i) 
{ 
    std::lock_guard<std::mutex> lk(values_mutex); 
    values.push_back(i); 
} 
+0

Basit bir kodla çoğaltılamadığım daha karmaşık bir sorun yaşadım. Bunun için üzgünüm. – deepskyblue86

+9

Sizin kodunuz istisnai güvenlikli değildir. Eğer push_back atarsa, deadlock yapacaksın, yerine std :: lock_guard' kullan. – inf

+1

@bamboon, iyi nokta ve güncellendi. – hmjd