私はミューテックスを持たない単純なシステムで作業していますが、ハードウェアバイナリセマフォの限られた配列です。通常、すべてのマルチスレッド化は重いセマフォ技術を使用して行われ、コードのパフォーマンスが低下し、デッドロックなしで正しく記述することが難しくなります。
単純な実装では、クリティカル セクションへのアトミック アクセスを保証するために、1 つのセマフォをグローバルに使用します。ただし、これは、クリティカル セクションがアクセスされている場合、関連のないオブジェクト (異なる型であっても) がブロックされることを意味します。
この問題に対する私の現在の解決策は、単一のグローバル セマフォを使用してガード バイトへのアトミック アクセスを保証し、それによって特定のクリティカル セクションへのアトミック アクセスを保証することです。私は現在これを持っています:
while (true) {
while (mutexLock == Mutex::Locked) {
} //wait on mutex
Semaphore semaLock(SemaphoreIndex::Mutex); //RAII semaphore object
if (mutexLock == Mutex::Unlocked) {
mutexLock = Mutex::Locked;
break;
}
} //Semaphore is released by destructor here
// ... atomically safe code
mutexLock = Mutex::Unlocked;
いくつか質問があります。これは、この問題に取り組む最善の方法ですか? このコードはスレッドセーフですか? これは「二重チェックロック」と同じですか?もしそうなら、それは同じ問題を抱えているので、メモリバリアが必要ですか?
編集:これが実装されているシステムに関するいくつかのメモ...
これは、32kB RAM を搭載した RISC 16 ビット プロセッサです。強力なマルチスレッド機能を備えていますが、そのメモリ モデルは非常に原始的です。ロードとストアはアトミックであり、キャッシングも分岐予測も分岐ターゲット予測もなく、1 つのコアに多くのスレッドがあります。メモリバリアは、ほとんどの場合、ハードウェア上の理由 (キャッシュなし) ではなく、メモリを汎用レジスタにリロードする必要があることをコンパイラが認識できるようにするためのものです。