ホームページ >システムチュートリアル >Linux >組み込み開発エンジニアは、Linux カーネルの同期メカニズムについて知っておく必要があります。
###############序文######
同期とは、プロセス間、およびプロセスとシステム リソース間の相互作用です。 Linux カーネルはマルチタスクを使用するため、調整を確実にするために複数のプロセス間に同期メカニズムが必要です。
Linux カーネルには多くの同期メカニズムがあります。今日は、カーネル内の非同期メカニズムに焦点を当てて、カーネル内の非同期メカニズムと同期メカニズムに焦点を当てます。カーネルにおける非同期機構は、アプリケーション層の同期機構、つまりアプリケーション層スレッド間の通信と、カーネルの同期機構の2種類に分けられる。
1. プロセス間の通信
システムの正確性と一貫性を確保するために、Linux カーネルはプロセス間通信のプロセス中にブロッキング キューを使用してプロセス間通信を処理します。ブロッキング キューとは、メッセージの送信時にメッセージ キュー内の要素が作成されますが、すべてのメッセージが送信されるわけではなく、特定のメッセージの待機キューがいっぱいになった場合にのみメッセージが送信されることを意味します。受信側の待機キューにメッセージが存在しない場合は通知を受信し、受信側の待機キューにメッセージが存在する場合は通知を受信しません。
カーネルでは、ブロッキング キューは抽象化されています。つまり、プロセスがメッセージを送信すると、メッセージはブロックされます。したがって、ブロッキング キューは実際には同期メカニズムです。ブロッキング キューは、待機キュー ポインター (プッシュ/ポップ) を含む特定の関数を通じて新しいオブジェクトを作成します。待機キューがいっぱいになると、システムは待機キュー ポインタが指すオブジェクトを最初のプロセスのスレッドとして使用して通知を発行します。つまり、プロセスはタスクの実行を続行する前に通知を受けます。
セマフォはメッセージの送受信に使用できます。プロセスがセマフォを所有するということは、それ自体のプライベート変数である独自のセマフォをすでに所有していることを意味します。このプライベート変数は他のプロセスでは取得できません。セマフォは、プロセスが所有するセマフォの数を表すために使用され、このプロセスがセマフォを所有すると、他のプロセスにメッセージを送信できます。このプライベート変数は、このプロセス自体によってのみ使用が許可されており、他のプロセスのプロセスに使用することはできません。
スレッドに独自のセマフォがある場合、スレッドは共有変数を通じて他のスレッドと通信できます。共有変数は他のスレッドでも使用され、他のスレッドは共有変数を使用してスレッド自体と通信します。
Mutex は主にシステム リソース用です。 Linux カーネルのミューテックスは、共有リソースとグローバル ミューテックス リソースの 2 つのタイプに分類できます。
共有リソースはプロセス間で共有されます。たとえば、プロセスに複数のスレッドがある場合、各スレッドはこの共有メモリ空間にアクセスできます。グローバルの相互排他的リソースとは、プロセスとスレッドがそれらが配置されているグローバル メモリ空間にのみアクセスできることを意味します。システムでは、ミューテックスを使用して、複数のプロセスがメモリ内で同時に実行できるようにすることができます。ただし、同時に実行する複数のプロセスを実装する場合は、同期メカニズムを使用して、すべてのプロセスが同じメモリ内で実行できるようにする必要があります。ミューテックスを使用すると、プロセスはそれが配置されているグローバル メモリ空間にのみアクセスできますが、他のメモリ空間にはアクセスできません。しかし、ミューテックスにはプロセスのブロックがなくなるという大きな利点があります。
メッセージキューの出現により、プロセス間通信が大幅に拡張されました。カーネルには、同期メカニズムに加えて、メッセージ キューという別の非同期メカニズムがあります。 Linux カーネルがメッセージ キューをサポートしていることは誰もが知っています。カーネルにはメッセージ キューに関する詳細情報がありますが、カーネルはユーザー モード メッセージ キューをサポートしていないため、メッセージ キューを理解するにはアプリケーション層から始める必要があります。
まず、メッセージキューとは何かを理解しましょう。
メッセージ キューは、複数のアプリケーション スレッド間の同期ニーズを満たすことができる特別なキューです。メッセージ キューは、アプリケーションと他のプロセスまたはスレッドとの間の非同期通信を提供するために使用されます。非同期通信が必要な場合は、メッセージ キューを使用して通信できます。たとえば、clear() 関数を呼び出すと、登録されたメッセージ キューを直接使用できます。
では、メッセージキューを作成するにはどうすればよいでしょうか? ext2.json を使用する場合、JAR.json.clear() のセマフォ コマンドを使用してメッセージ キューを作成できます。
共有メモリでは共有ロックを使用しますが、共有ロックは特定のプロセスとメモリを共有するため、共有ロックを取得したい場合は他のプロセスに要求する必要があります。
上の例と同様に、volatile キーワードを使用して共有メモリにアクセスします。この時点では他のプロセスからリクエストを行っていないため、この共有ロックを取得したい場合は他のプロセスからリクエストするだけで済みます。これにより、2 つのプロセス間の競合が回避され、データの同期が実現されます。
共有ロックはプロセスとメモリを共有するため、プロセスにそのアドレスへのアクセスを要求する必要があります。この状況に対する最も簡単な解決策は、スレッド プールを使用することです。
スレッド プールには「byte」というオブジェクトがあり、これも共有ロックです。このロックを取得するには、バイト オブジェクトにリクエストを送信するだけです。このとき、バイトオブジェクトはリクエストをスレッドのキューに送り、スレッドがリクエストを受け取ると応答メッセージを返します。
スレッド プールは非常に優れたスレッド管理ツールであり、複数のスレッドの同時実行を可能にし、スレッド間のデッドロックや競合を軽減することもできます。最も重要な機能の 1 つは、システムのメモリを効果的に利用して効率を向上できることです。
スレッド プールの使用は非常に簡単で、実行するタスクを対応するスレッド プールに割り当てるだけです。実行対象のタスクが対応するスレッドプールに割り当てられている場合、実行可能になります。スレッド プールを使用すると、多くのメリットが得られます:
上で 2 つの同期メカニズムを紹介しましたので、カーネル状態の同期メカニズムを見てみましょう。カーネル状態には 4 つの同期方法があります:
上記の分析を通じて、同期は複雑な問題であることがわかりましたが、カーネル状態では同期はどのように完了するのでしょうか?
まず第一に、カーネル状態には 3 つのプロセスがあります。これら 3 つのプロセスは相互にリソースにアクセスでき、他のプロセスによってリソースが要求されたときに同期することもできます。
プロセスがブロックされると、そのすべての子プロセスは待機キューから子プロセス (または他の子プロセス) を取り出し、ブロック キューに追加します。すべての子プロセスがブロックされると、ブロック キューに子プロセスは存在しません。このとき、待機キュー内の他の子プロセスは、現在のスレッドを待機キューに追加します。これら 3 つのプロセスは待機中に相互に影響を与えることはなく、独自の優先順位を設定することで他のスレッドと同期することができます。
以上が組み込み開発エンジニアは、Linux カーネルの同期メカニズムについて知っておく必要があります。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。