竞争条件仿真在xcode中崩溃

时间:2013-07-17 21:21:35

标签: c++ xcode race-condition

我正在尝试用C ++模拟竞争条件。下面是我的代码,我使用xcode作为我的IDE

相关代码如下:

int main(int argc, const char * argv[])
{
int value=0;
int* ptr = &value;

racer r1(ptr, "John");
racer r2(ptr, "Mike");

std::thread my_thread1(r1);
std::thread my_thread2(r2);

//guard g1(my_thread1);
//guard g2(my_thread2);

my_thread1.join();
my_thread2.join();

cout<<"result:= "<<*ptr<<endl;
cout <<"end!"<<endl;
return 0;

}

对于我的赛车:

racer::racer(int* r, char const* name)
{
    this->r=r;
    this->name=name;
}

void racer::print_result()
{
     cout<<this->name<<" "<<*r<<endl;
}

void racer::count_now()
{ 
    for ( int i = 0; i < 50; i++ )
    {
       *r = *r + 1;
       cout<<this->name<<". "<<*r<<endl;
    }
 }


void racer::operator()()
{
     count_now();
} 

所以基本上,我没有比赛的预期结果是* ptr = 100,因为有2个线程在同一个资源上一起运行。因此,有时当我运行它时,我得到100,有时它会崩溃,我收到下面的错误消息。这是为什么?换句话说,为什么我不能得到> 100的值?什么时候崩溃是否意味着我有竞争条件,因此错误?

enter image description here

2 个答案:

答案 0 :(得分:1)

首先是一个简单的问题:因为你使用Xcode我假设你使用的是基于x86的处理器。我的理解是,您将无法按照您尝试的方式生成简单的数据竞争,因为基于x86的Intel处理器实现了强大的缓存一致性协议,更准确地说是MESI protocol。在具有较弱缓存一致性协议的不同系统上,例如,在基于ARM的处理器上,我认为你会得到有趣的值,但目前我无法尝试。

更难的问题是:为什么会崩溃?调试器清楚地显示了IOStreams库中的崩溃,这似乎是由std::cout的并发访问引起的。但是,在调试器指向的行中,我无法真正看到空指针取消引用的来源。唯一被解除引用的指针是this(函数std::basic_streambuf<...>::overflow()virtual函数,即需要访问虚函数表。)

答案 1 :(得分:1)

您的示例代码不太可能产生竞争条件。竞争条件的前提条件是线程之间的上下文切换。你的例子太简单了

1) only two threads.
2) Each thread, on linux, by default, gets about 50ms CPU time for each context switch.

您的代码只有50(增量+ cout)。这50个循环可以在50ms内轻松完成,因此两个线程将在执行时完成而无需任何上下文切换。如果没有(足够的)上下文切换,您将无法见证任何种族关系。

提高你的机会:

1) start 50 threads.
2) each thread execute 50 loops.
3) each loop does 10 increments.

或增加1)中的数字2)3)直到你开始看到许多上下文切换并希望导致竞争条件。一个前兆将是输出消息混合(“John”,“Mike”......)