0

C++ で競合状態をエミュレートしようとしています。以下は私のコードで、IDEとしてxcodeを使用しています

関連するコードは次のようになります。

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 を超える値を取得できないのはなぜですか? クラッシュした場合、競合状態が発生してエラーが発生したことを意味しますか?

ここに画像の説明を入力

4

2 に答える 2

1

サンプル コードで競合状態が発生する可能性はほとんどありません。競合状態の前提条件は、スレッド間のコンテキスト スイッチです。あなたの例は単純すぎる

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

コードには 50 (インクリメント + cout) しかありません。この 50 ループは 50 ミリ秒で簡単に完了することができるため、両方のスレッドは実行中にコンテキストを切り替えることなく完了します。(十分な) コンテキスト スイッチがなければ、競合状態を目撃することはありません。

可能性を高めるには:

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

または、1) 2) 3) の数を増やして、多くのコンテキスト スイッチが表示され始め、できれば競合状態が発生するようにします。前兆は、出力メッセージが混在していることです(「ジョン」、「マイク」...)

于 2013-07-17T23:33:30.967 に答える