カウントとバイナリセマフォの違いは何ですか。
私がどこかで見たのは、両方がリソースを要求したN個のプロセスを制御できるということです。両方とも、自由状態を取りました。
バイナリセマフォとカウンティングセマフォが保護できるリソースの数に制限はありますか?
どちらも、一度に1つのプロセスのみがリソースを使用できるようにします...
他に違いはありますか?上記のプロパティは正しいですか?
カウントとバイナリセマフォの違いは何ですか。
私がどこかで見たのは、両方がリソースを要求したN個のプロセスを制御できるということです。両方とも、自由状態を取りました。
バイナリセマフォとカウンティングセマフォが保護できるリソースの数に制限はありますか?
どちらも、一度に1つのプロセスのみがリソースを使用できるようにします...
他に違いはありますか?上記のプロパティは正しいですか?
実際には、アクセスしようとしているエンティティがプロセスであるかスレッドであるかに関係なく、両方のタイプを使用して共有リソースへのアクセスを同期します。
違いは次のとおりです。
バイナリセマフォはバイナリであり、2つの値のみを持つことができます。1つはプロセス/スレッドがクリティカルセクション(共有リソースにアクセスするコード)にあり、他は待機する必要があることを表し、もう1つはクリティカルセクションが空いていることを示します。
一方、セマフォのカウントには3つ以上の値が必要であり、任意の値を指定できます。それらが取る最大値Xにより、Xプロセス/スレッドは共有リソースに同時にアクセスできます。
詳細については、このリンクを参照してください。
http://www.chibios.org/dokuwiki/doku.php?id=chibios:articles:semaphores_mutexes
編集
カウントセマフォが取ることができる最大値は、同時にクリティカルセクションに許可したいプロセスの数です。
繰り返しになりますが、特定のリソースを除外したい場合でも、このリソースには最大数のプロセス(たとえば、X)でアクセスできることがわかっているため、値Xでカウントセマフォを設定します。
これにより、Xプロセスが同時にそのリソースにアクセスできるようになります。それでも、プロセスX + 1は、クリティカルセクションのプロセスの1つが終了するまで待機する必要があります。
並行プログラムを構築するには、同期と相互排除という2つの重要な概念があります。これらの2つのタイプのロック(セマフォはより一般的には一種のロックメカニズムです)が同期と相互排除の実現にどのように役立つかを見ていきます。
セマフォには、カウンターと、特定のリソースへのアクセスを待機しているタスクのリストの2つの部分があります。セマフォは2つの操作を実行します:待機(P)[これはロックの取得に似ています]と解放(V)[ロックの解放に似ています]-これらはセマフォで実行できる唯一の2つの操作です。バイナリセマフォでは、カウンタは論理的に0から1の間になります。これは、open/closedの2つの値を持つロックに似ていると考えることができます。カウントセマフォには、カウントに複数の値があります。
理解しておくべき重要なことは、セマフォカウンターは、ブロックする必要のないタスクの数を追跡することです。つまり、タスクは進行する可能性があります。タスクはブロックされ、カウンターがゼロの場合にのみセマフォのリストに追加されます。したがって、タスクが進行できない場合、タスクはP()ルーチンのリストに追加され、V()ルーチンを使用して「解放」されます。
さて、同期と相互排除を解決するためにバイナリセマフォをどのように使用できるかを理解することはかなり明白です-それらは本質的にロックです。
元。同期:
thread A{
semaphore &s; //locks/semaphores are passed by reference! think about why this is so.
A(semaphore &s): s(s){} //constructor
foo(){
...
s.P();
;// some block of code B2
...
}
//thread B{
semaphore &s;
B(semaphore &s): s(s){} //constructor
foo(){
...
...
// some block of code B1
s.V();
..
}
main(){
semaphore s(0); // we start the semaphore at 0 (closed)
A a(s);
B b(s);
}
上記の例では、B2はB1が実行を終了した後にのみ実行できます。スレッドAが最初に実行され、sem.P()に到達し、カウンターが0(閉じている)であるため、待機するとします。スレッドBがやって来て、B1を終了し、次にスレッドAを解放します。これでB2が完了します。したがって、同期を実現します。
次に、バイナリセマフォを使用した相互排除を見てみましょう。
thread mutual_ex{
semaphore &s;
mutual_ex(semaphore &s): s(s){} //constructor
foo(){
...
s.P();
//critical section
s.V();
...
...
s.P();
//critical section
s.V();
...
}
main(){
semaphore s(1);
mutual_ex m1(s);
mutual_ex m2(s);
}
相互排除も非常に単純です。m1とm2が同時にクリティカルセクションに入ることができません。したがって、各スレッドは同じセマフォを使用して、2つのクリティカルセクションを相互排除します。さて、より大きな並行性を持つことは可能ですか?クリティカルセクションによって異なります。(他にどのようにセマフォを使用して相互排除を実現できるかを考えてください。ヒント:必ずしも1つのセマフォのみを使用する必要がありますか?)
セマフォのカウント:複数の値を持つセマフォ。これが何を意味しているのかを見てみましょう-複数の値を持つロック?開いて、閉じて、そして...うーん。相互排除または同期におけるマルチステージロックはどのような用途に使用されますか?
2つのうち簡単なものを取り上げましょう。
カウントセマフォを使用した同期:3つのタスクがあるとします。3の後に実行する#1と2です。同期をどのように設計しますか?
thread t1{
...
s.P();
//block of code B1
thread t2{
...
s.P();
//block of code B2
thread t3{
...
//block of code B3
s.V();
s.V();
}
したがって、セマフォが閉じた状態で開始する場合は、t1およびt2ブロックがセマフォのリストに追加されるようにします。次に、すべての重要なt3が登場し、ビジネスを終了してt1とt2を解放します。彼らはどのような順序で解放されますか?セマフォのリストの実装によって異なります。FIFOである可能性があり、特定の優先順位に基づく可能性があります。(注:t1とt2を特定の順序で実行したい場合、およびセマフォの実装に気付いていない場合は、PとVをどのように配置するかを考えてください)
(調べてください:Vの数がPの数よりも多い場合はどうなりますか?)
カウントセマフォを使用した相互排除:このための独自の擬似コードを作成してください(理解を深めることができます!)-しかし、基本的な概念は次のとおりです:counter = Nのカウントセマフォにより、N個のタスクがクリティカルセクションに自由に入ることができます。これは、N個のタスク(または必要に応じてスレッド)がクリティカルセクションに入るが、N + 1番目のタスクがブロックされ(お気に入りのブロックされたタスクリストに追加され)、誰かVがセマフォである場合にのみ通過することを意味します少なくとも一度は。したがって、セマフォカウンターは、0と1の間でスイングするのではなく、0とNの間で移動し、N個のタスクが自由に出入りできるようになり、誰もブロックしなくなります。
さて、なぜあなたはそのような奇妙なロックが必要なのでしょうか?複数の人がリソースにアクセスできないようにすることは、相互排除の全体的なポイントではありませんか?考え。(ヒント...コンピュータにドライブが1つしかないわけではありませんか?...?)
考える:相互排除は、セマフォを数えるだけで達成されますか?リソースのインスタンスが10個あり、10個のスレッドが(カウントセマフォを介して)入って、最初のインスタンスを使用しようとした場合はどうなりますか?
カウントとバイナリセマフォの最も基本的な違いは次のとおりです。
構造の実装バイナリセマフォ:int s;
セマフォのカウント:Struct S {int s; キューq; }
カウントセマフォを使用して、CS(クリティカルセクション)を取得したプロセスは、他のプロセスがCSを取得するのを待機する必要があるため、単一のプロセスが起動することはありません。各プロセスはCSのチャンスを得ます。