pthreadsとUbuntu開発環境に基づいたスレッドで、最新のgccでmutexとメッセージの受け渡しに興味があります。このための良い一般的な問題は、各哲学者が左と右の隣人と共有するlhとrhフォークを使用する食堂の哲学者です。私はクアッドコアプロセッサを忙しくするために哲学者の数を99に増やしています。C++でのスレッドのパフォーマンス11
int result = try_lock(forks[lhf], forks[rhf]);
上記のコードは私の哲学者は、彼らが一緒に食べる必要がある2本のフォークをつかむしようとすることができます。
// if the forks are locked then start eating
if (result == -1)
{
state[j] = philosophers::State::Eating;
eating[j]++;
if (longestWait < waiting[j])
{
longestWait = waiting[j];
}
waiting[j] = 0;
} else {
state[j] = philosophers::State::Thinking;
thinking[j]++;
waiting[j]++;
}
上記のコードは、彼らが2本のフォークを確保するために管理している場合、私の哲学者が応じて食べたり考え進捗を監視します。
{
testEnd te(eating[j]+thinking[j]-1);
unique_lock<mutex> lk(cycleDone);
endCycle.wait(lk, te);
}
上記のコードは、哲学者は、新たな試みを作るために自由であるこの時間の後に選択を完了するために、すべての哲学者を待ち:
if (philosophers::State::Eating == state[j])
{
state[j] = philosophers::State::Thinking;
forks[lhf].unlock();
forks[rhf].unlock();
}
私は哲学者や移動を監視し、メインスレッドを持っていますそれらを1つのサイクルから次のサイクルに移して、約10秒間食べてできるだけ多く考えることができます。 結果は約9540サイクルあり、飢えている哲学者や食べたくなる人が多く、思考時間が多いです!だから私は、リリースと考えるように食べるの哲学者を必要とするのではなく、非常に小さな休憩後に同じフォークをGABによって食べオーバーを防止するために、飢餓や長すぎる待ってから、私の哲学者を保護するので、私はより多くのロジックを追加する必要があります。
// protect the philosopher against starvation
if (State::Thinking == previous)
{
result = try_lock(forks[lhf], forks[rhf]);
}
今私は9598サイクルを持っていて、すべての哲学者が食べるのに比較的等しいシェア(2620 - 2681)を得て、最長で14秒待って考えます。しかし私は満足していないので、今私はミューテックスとロックをすべて取り除き、偶数サイクルで食べる哲学者と奇妙なサイクルで食べる奇妙な哲学者とを単純にします。私は
while (counter < counters[j])
{
this_thread::yield();
}
は、グローバルサイクルカウンタを使用して何回も食べるか考えてから哲学を防ぎ哲学を同期する簡単な方法を使用します。同じ時間と哲学者は、36400回の食事で約73543サイクルを管理し、3サイクル以上を待っています。だから、ロックなしの私の単純なアルゴリズムは、高速であり、さまざまなスレッド間の処理のより良い分布を持っています。
誰もがこの問題を解決する良い方法を考えることができますか?私は、複数のスレッドを持つ複雑なシステムを実装すると、従来のミューテックスとメッセージパッシングの手法に従えば、システムのさまざまなスレッドで必要以上に不均衡な処理が遅くなることに懸念しています。
ランダムに生成されたものよりも、最適であることが知られている手作業による同期スケジュールが勝利します。すばらしいです。問題はどこだ? –
C++ 1yの 'std :: hemlock'プロポーザルは、この問題を一度解決しなければなりません。 –
これはC++ 11自体とは何の関係もないようです。 –