Linux ロックの種類: 1. mutex (ミューテックス ロック)、常に 1 つのスレッドだけがオブジェクトにアクセスできるようにするために使用されます; 2. rwlock (読み取り/書き込みロック)、読み取りロックと書き込みロックに分割されます。 lock (データの読み取り頻度がデータの書き込み頻度よりはるかに高い状況に適しています)、3. スピンロック (スピン ロック)、常に 1 つのスレッドのみがオブジェクトにアクセスできます、4. seqlock (シーケンシャル ロック)、読み出しと書き込みが区別でき、読み出しが多く書き込みが少なく、読み出しよりも書き込みの優先順位が高い場合に使用されます。
#このチュートリアルの動作環境: linux7.3 システム、Dell G3 コンピューター。
ミューテックス ロック: mutex
ミューテックス ロック: ミューテックス、いつでも確実にロックされるようにするために使用されます。 、オブジェクトにアクセスできるスレッドは 1 つだけです。ロックの取得操作が失敗すると、スレッドはスリープ状態になり、ロックが解放されるのを待つときに目覚めます。
読み取り/書き込みロック: rwlock
読み取り/書き込みロック: rwlock、読み取りロックと書き込みロックに分かれています。読み取り操作中、複数のスレッドが同時に読み取り操作を取得できるようにすることができます。ただし、同時に書き込みロックを取得できるスレッドは 1 つだけです。書き込みロックの取得に失敗した他のスレッドは、書き込みロックが解放されて目覚めるまでスリープ状態になります。
注: 書き込みロックは、他の読み取りおよび書き込みロックをブロックします。スレッドが書き込みロックを取得して書き込みを行っている場合、他のスレッドは読み取りロックを取得できません。ライターはリーダーよりも優先されます (ライターが存在すると、後続のリーダーは待機する必要があり、ウェイクアップ時にライターが優先されます)。
スピン ロック:スピンロック
スピン ロック:スピンロック。オブジェクトにアクセスできるのは、一度に 1 つのスレッドだけです。ただし、ロックの取得操作が失敗すると、スリープ状態にならず、ロックが解放されるまでその場でスピンします。これにより、スリープ状態からウェイクアップまでのスレッドの消費が節約され、ロック時間が短い環境での効率が大幅に向上します。ただし、ロック時間が長すぎると、大量の CPU リソースが浪費されます。
RCU
RCU: 読み取り、コピー、更新。データを変更する場合は、まずデータを読み取り、次にコピーを生成し、そのコピーを変更する必要があります。修正が完了したら、古いデータを新しいデータに更新します。
RCU を使用する場合、リーダーは同期オーバーヘッドをほとんど必要とせず、ロックを取得したり、アトミック命令を使用したりする必要がないため、ロックの競合が発生しないため、デッドロックの問題を考慮する必要がありません。ライターの同期オーバーヘッドは比較的大きく、変更されたデータをコピーする必要があり、ロック メカニズムを使用して他のライターの変更操作を同期および並列化する必要があります。これは、読み取り操作が多数で書き込み操作が少ない場合に非常に効率的です。
セマフォ: セマフォ
Linux カーネルのセマフォは、概念および原理においてユーザー モード SystemV の IPC メカニズム セマフォと同じですが、カーネルの外部では決して使用できないため、SystemV の IPC メカニズムのセマフォとは何の関係もありません。
セマフォは作成時に初期値を設定する必要があります。これは、複数のタスクがセマフォによって保護された共有リソースに同時にアクセスできることを意味します。初期値 1 はミューテックス (Mutex) になります。つまり、同時に 1 つのタスクだけがセマフォによって保護された共有リソースにアクセスできます。タスクが共有リソースにアクセスしたい場合は、まずセマフォを取得する必要があります。セマフォを取得する操作により、セマフォの値が 1 ずつ減ります。セマフォの現在の値が負の数である場合、セマフォが有効であることを示します。セマフォの待機キューは、セマフォが使用可能になるのを待ちます。セマフォの現在の値が負でない数値であれば、それはセマフォを取得できることを意味します。そのため、セマフォによって保護されている共有リソースにすぐにアクセスできます。タスクは、セマフォによって保護されている共有リソースへのアクセスを完了したら、セマフォを解放する必要があります。セマフォの解放は、セマフォの値に 1 を加算することで実現されます。セマフォの値が正以外の数値の場合、セマフォはセマフォを解放します。は、現在のセマフォを待機しているタスクがあることを示すため、セマフォを待機しているすべてのタスクも起動します。
rw_semaphore (読み取りおよび書き込みセマフォ)
読み取りおよび書き込みセマフォは、訪問者 (読み取りまたは書き込み) を細分化します。読み取りおよび書き込みセマフォは、読み取りおよび書き込みセマフォを維持しながら、読み取りおよび書き込みセマフォによって保護された共有リソースの読み取りおよびアクセスのみ可能です。書き込む必要があるため、ライターとして分類する必要があります。共有リソースにアクセスする前にライター ステータスを取得する必要があります。書き込みアクセスが必要ないと判断した場合、ライターはリーダーにダウングレードできます。読み取り/書き込みセマフォが同時に持つことができるリーダーの数に制限はありません。つまり、任意の数のリーダーが同時に読み取り/書き込みセマフォを所有できることになります。読み書きセマフォが現在ライターによって所有されておらず、リーダーがセマフォを解放するのを待っているライターがいない場合、どのリーダーも読み書きセマフォを正常に取得できます。そうでない場合、リーダーはライターがセマフォを解放するまで一時停止する必要があります。セマフォ。読み書きセマフォが現在リーダーまたはライターによって所有されておらず、セマフォを待っているライターがいない場合、ライターは読み書きセマフォを正常に取得できます。そうでない場合、ライターは訪問者がいなくなるまで一時停止されます。 。したがって、作家は排他的で排他的です。
読み取りセマフォと書き込みセマフォには 2 つの実装があります。1 つはユニバーサルであり、ハードウェア アーキテクチャに依存しません。したがって、新しいアーキテクチャを追加しても再実装する必要はありません。ただし、パフォーマンスが低く、実装が難しいという欠点があります。読み取りおよび書き込みセマフォの取得と解放。オーバーヘッドが高い。もう 1 つはアーキテクチャ関連であるため、パフォーマンスが高く、読み取りおよび書き込みセマフォの取得と解放のオーバーヘッドは小さいですが、新しいアーキテクチャを追加するには再実装が必要です。カーネルの構成中に、オプションを使用して、どの実装を使用するかを制御できます。
読み取りおよび書き込みセマフォ: rw_semaphore
読み取りおよび書き込みセマフォは、リーダーまたはライターのいずれかの訪問者を細分化します。リーダーは、セマフォ期間中のみ読み取りと書き込みを維持します。読み取り/書き込みセマフォによって保護された共有リソースは、読み取りとアクセスが可能です。タスクが読み取りに加えて書き込みも必要な場合、そのタスクは書き込みタスクとして分類され、共有リソースにアクセスする前に、まず共有リソースにアクセスする必要があります。ライターのステータスを取得すると、書き込みアクセスが必要なくなった場合、ライターはリーダーにダウングレードできます。読み取り/書き込みセマフォが同時に持つことができるリーダーの数に制限はありません。つまり、任意の数のリーダーが同時に読み取り/書き込みセマフォを所有できることになります。読み書きセマフォが現在ライターによって所有されておらず、リーダーがセマフォを解放するのを待っているライターがいない場合、どのリーダーも読み書きセマフォを正常に取得できます。そうでない場合、リーダーはライターがセマフォを解放するまで一時停止する必要があります。セマフォ。読み書きセマフォが現在リーダーまたはライターによって所有されておらず、セマフォを待っているライターがいない場合、ライターは読み書きセマフォを正常に取得できます。そうでない場合、ライターは訪問者がいなくなるまで一時停止されます。 。したがって、作家は排他的で排他的です。
読み取りセマフォと書き込みセマフォには 2 つの実装があります。1 つはユニバーサルであり、ハードウェア アーキテクチャに依存しません。したがって、新しいアーキテクチャを追加しても再実装する必要はありませんが、パフォーマンスが低く、取得が難しいという欠点があります。セマフォのオーバーヘッドが高い、もう 1 つはアーキテクチャ関連であるためパフォーマンスが高く、読み取りおよび書き込みセマフォの取得と解放のオーバーヘッドは小さいですが、新しいアーキテクチャを追加する場合は再実装が必要です。カーネルの構成中に、オプションを使用して、どの実装を使用するかを制御できます。
seqlock**** (シーケンシャルロック)
は、読み取りと書き込みが区別でき、読み取り操作が多く書き込み操作が少ない状況で使用されます。読み取り操作よりも優先されます。 seqlock の実装のアイデアは、シーケンスを表すために増加する整数を使用することです。書き込み操作がクリティカル セクションに入ると、シーケンスは になり、クリティカル セクションから出ると、シーケンスは再び になります。
書き込み操作もロック (ミューテックスなど) を取得する必要があります。このロックは、同時に進行中の書き込み操作が 1 つだけであることを保証するために、書き込み-書き込みミューテックスにのみ使用されます。シーケンスが奇数の場合は書き込み動作中であることを意味しますが、このときリード動作はシーケンスが偶数になるまでクリティカルセクションに入るまで待つ必要があります。読み取り操作がクリティカル セクションに入ると、現在のシーケンスの値を記録する必要があります。クリティカル セクションから出ると、記録されたシーケンスと現在のシーケンスを比較します。それらが等しくない場合は、書き込み操作が発生したことを意味します読み取り操作がクリティカル セクションに入ったとき、読み取り操作は無効であるため、戻って再試行する必要があります。
Seqlock の書き込みは相互に排他的である必要があります。ただし、seqlock の適用シナリオ自体は、読み取りが多く書き込みが少なく、書き込み競合が発生する可能性は非常に低い状況です。したがって、ここでの書き込み-書き込みミューテックスでは基本的にパフォーマンスの低下はありません。読み取り操作と書き込み操作は相互に排他的である必要はありません。 seqlock の適用シナリオは、書き込み操作が読み取り操作より優先されるというもので、書き込み操作の場合は (書き込みと書き込みの競合などの小さな確率のイベントが発生しない限り) ブロッキングはほとんどなく、シーケンスの追加アクションのみが必要です。読み取り操作をブロックする必要はありませんが、読み取りと書き込みの競合が見つかった場合は再試行が必要です。 seqlock の典型的な用途はクロックの更新です。システム内で 1 ミリ秒ごとにクロック割り込みが発生し、対応する割り込みハンドラーがクロックを更新します (書き込み操作)。
ユーザー プログラムは、gettimeofday などのシステム コールを呼び出して、現在時刻を取得できます (読み取り操作)。この場合、seqlock を使用すると、多くの gettimeofday システム コールが割り込みハンドラーをブロックするのを防ぐことができます (これは、seqlock の代わりに読み取り/書き込みロックが使用されている場合に当てはまります)。常に割り込みハンドラが優先され、gettimeofday システムコールが割り込みハンドラと競合した場合、ユーザプログラムが待っても問題ありません。
1) 読み取り/書き込みロックはリーダーとライターを区別しますが、ミューテックス ロックは区別しません
2) ミューテックス ロックは次のことのみを行うことができます。読み取りまたは書き込みに関係なく、1 つのスレッドがオブジェクトにアクセスできます。読み取り/書き込みロックでは、同時に 1 つの書き込み者のみが許可されますが、複数の読み取り者が同時にオブジェクトを読み取ることができます。
関連する推奨事項: 「Linux ビデオ チュートリアル 」
以上がLinux ロックにはどのような種類がありますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。