2017-06-14 29 views
0

为什么我的代码中没有任何竞争条件? 由于源这里:http://en.cppreference.com/w/cpp/memory/shared_ptrshared_ptr中的竞争条件不会发生

如果执行访问多个线程相同的shared_ptr不同步和任何这些访问的使用的shared_ptr的非const成员函数然后将出现数据争用;

class base 
{ 
public: 
    std::string val1; 
}; 

class der : public base 
{ 
public: 
    std::string val2; 
    int val3; 
    char val4; 
}; 

int main() 
{ 
    std::mutex mm; 
    std::shared_ptr<der> ms(new der()); 

    std::thread t1 = std::thread([ms, &mm]() { 
     while (1) 
     { 
     //std::lock_guard<std::mutex> lock(mm); 

      std::string some1 = ms->val2; 
      int some2 = ms->val3; 
      char some3 = ms->val4; 
      ms->val2 = "1232324"; 
      ms->val3 = 1232324; 
      ms->val4 = '1'; 
     } 
    }); 

    std::thread t2 = std::thread([ms, &mm]() { 
     while (1) 
     { 
      //std::lock_guard<std::mutex> lock(mm); 

      std::string some1 = ms->val2; 
      int some2 = ms->val3; 
      char some3 = ms->val4; 
      ms->val2 = "123435"; 
      ms->val3 = 123435; 
      ms->val4 = '3'; 
     } 
    }); 

    std::shared_ptr<base> bms = ms; 
    std::thread t3 = std::thread([bms]() { 
     while (1) 
     { 
      bms->val1 = 434; 
     } 
    }); 

    while (1) 
    { 
     std::this_thread::sleep_for(std::chrono::milliseconds(1)); 
    } 
} 
+1

代码中存在数据竞争。编译器不会给你一个错误,但它只是产生未定义的代码。 – NathanOliver

+0

你有数据竞赛**和**比赛条件,它们是不同的。然而,在你的例子中'shared_ptr'没有,它全部在'der' –

+0

@Passer By上,但是那里'std :: shared_ptr'的'operator->'可能有竞争条件。据我所知,为了避免它,我应该使用'std :: atomic_load'并获取'std :: shated_ptr'的副本以在另一个'std :: thread'中使用。 –

回答

3

数据竞争不会产生编译失败;他们产生未定义的行为。该行为可能是“正常工作”。或者“似乎工作正常,但巧妙地在12分钟后打破某些东西”。或者“立即失败”。

只是因为代码出现工作并不意味着它实际上。对于线程代码,这比其他任何类型更为真实。

0

我会建议你使用valgrind tool - helgrind。 调试多线程程序时,很难找到竞争条件。 要运行此工具,您需要在您的计算机上使用valgrind并运行它:

valgrind --tool=helgrind ./Your_Complied_File arg1 arg2 ...