2

クラス Test に 4 つの関数があります。

void Test::A()
{
    boost::lock_guard<boost::mutex> lock(mutex);
    cout << "A!" << endl;
}

void Test::B()
{
    boost::lock_guard<boost::mutex> lock(mutex);
    cout << "B!" << endl;
}

void Test::C()
{
    boost::lock_guard<boost::mutex> lock(mutex);
    cout << "C!" << endl;
}

void Test::D()
{
    boost::lock_guard<boost::mutex> lock(mutex);
    cout << "D!" << endl;
}

アルファベット順に呼び出しTest::ATest::D、ループ内で何度も呼び出し、boost thread_pool にバインドすると、ほとんどの場合、正常に動作します。ただし、場合によっては、cout ステートメントが順不同で出力されることがあります。したがって、 ABCDABCDABCDAB が表示される場合がありますD C。私が理解していることから、それは thread_pool が新しいスレッドを取得したときに関係しているだけであり、呼び出される順序を制御することはできません.

私の問題は、C() と D() を順番に呼び出す必要があり (呼び出す必要がある場合)、A() と B() の相対的な順序や C() と C() を気にしないことです。 D()。そのため、thread_pool を介して C と D を呼び出す代わりに、メイン プロセスを介して呼び出し、すべてのミューテックスを保持しています。ループ内のすべての関数を再度呼び出そうとすると、C の cout ステートメントの直前でプログラムがハングします。なぜそうなのか、私は困惑しています。メイン プロセスとそのスレッド全体でミューテックスを使用できませんか?

これらの関数の単純化された性質にもかかわらず、これらの関数は最終的にイベント ベースの関数にアップグレードされるため、C と D のロジックを組み合わせることができません。それらを何度も呼び出すループは、実際のイベントをシミュレートするための単なるダミー ループです。D は常に C の後に呼び出されますが、呼び出される場合と呼び出されない場合があります。

例えば:

あいうえお

ABCCD

広告

ABCCC

4

4 に答える 4

2

C と D を別々のイベントでトリガーできる (つまり、同じスレッドで順番に呼び出すことはできない) が、C の前に D を実行してはならない場合は、条件変数またはその他の同期手段を使用する必要があります。 (おそらくセマフォ)。

すでにブーストを使用しているので、ブースト条件変数を確認することをお勧めします

于 2013-08-13T13:55:15.600 に答える
1

これは完全に正常です。最初に A、次に B の2 つのスレッドプール スレッドを開始すると、A が B より先に cout ステートメントに到達するという保証はまったくありません。それは単に可能性があります。あなたが作成したバグは「スレッド競合」と呼ばれ、スレッドを使用するコードで非常に一般的なバグであり、診断と修正が難しいことで有名です。

これらのスレッドは独自のペースで実行されます。オペレーティング システムが A をプリエンプトし、B をプリエンプトしない場合 (たとえば、別のプロセスの別のスレッドを実行できるようにする場合)、B は確実に A より先に競合し、最初に cout ステートメントに到達します。これらの cout ステートメントが厳密に順番に実行されるようにする唯一の簡単な方法は、1 つのスレッドを使用することです。

于 2013-08-13T13:18:24.233 に答える
1

実行順序を維持したい場合は、セマフォを調べてください。ロックは FIFO であるため、最初にロックを取得したスレッドが最初に実行されます。C が D の前に呼び出されるようにするには、次のようにします。

C : increment semaphore by 1
D : decrement semaphore by 1

セマフォが 0 から始まる場合、セマフォが 1 になると、D はセマフォをデクリメントすることができます (既に C によってインクリメントされています)。この場合、バイナリ セマフォを使用できます。可能な値は 0 または 1 です。

于 2013-08-16T21:19:57.503 に答える