Linux 入門 --- セマフォ

セマフォとは

セマフォの本質はカウンタであり、通常、パブリック リソース内のリソースの数を示すために使用されます。パブリック リソースとは、複数のプロセスが同時にアクセスできるリソースを指します。保護されていないパブリック リソースにアクセスすると、データの不整合が発生する可能性があります。例: プロセスがパブリック リソースに対して書き込み操作を実行します。書き込み操作が途中で完了すると、別のプロセスがパブリック リソースを読み取ります。このとき、データの不整合の問題が発生します。ここで少し立ち止まって、これを確認してみましょう論理: なぜ異なるプロセスに同じリソースを参照させる必要があるのでしょうか? プロセス間のコラボレーションを実現するために通信を実現したいのですが、プロセスは独立しており、プロセス間で直接通信する方法がないため、プロセス間で同じリソースを参照できるようにする必要があります。これが問題の解決策です。データの不整合という新たな問題が発生したため、通信を実現するパブリックリソースを保護しなければなりません。保護されたパブリックリソースをクリティカルリソースと呼びます。そうすると、今後私たちがしなければならないことは、パブリックリソースをどのように保護するかに関係します。公共リソースを保護する場合、セマフォが使用されます。プログラムのリソースのほとんどは独立しており、リソース (メモリ リソース、ファイル リソース、ネットワーク リソース) はプロセスによって使用されます。クリティカル リソースのこの部分にアクセスするには、プロセス内に対応するコードが必要です。クリティカル リソースにアクセスするコードをクリティカル セクションと呼び、クリティカルではないリソースにアクセスするコードを非クリティカル セクションと呼びます。これを見たら、ここのロジックを理解する必要があります。私たちが作成するプログラムは、パブリック リソースにアクセスします。パブリック リソースのセキュリティを保護するには、これらのリソースを保護する必要があります。保護のためにセマフォを使用する必要があります (使用方法については後で説明します)方法としては相互排他と同期があります。同期の概念については後ほど詳しく説明します。相互排他とは、あるリソースにアクセスしたり何かをするときに待たなければならないことを意味します。同じ理由は、あるリソースにアクセスするときにも当てはまります。または、何かをするとき、私は待たなければなりません。あなたがそれを終えた後、私や他の人はそれを続けることができます。そして、それを終えるか、やらないかの2つの状況を、原子性とシグナルと呼びます。量の役割は保護することですアトミック性による公共リソース。

なぜセマフォがあるのでしょうか?

映画館でチケットを購入する例を通してセマフォについて学ぶことができます。映画館でのチケット購入メカニズムは、実際には上映ホールの座席の予約メカニズムです。特定のリソースが必要なときに、そのリソースを予約できます。たとえば、私が映画のチケットを購入した後、映画館は特定の席の予約を手伝ってくれます。たとえ映画館に行かなくても、その席に他の人がいることはできません。したがって、映画館は映画のチケットが売れすぎたり、間違って売れたりしないようにする仕組みがあり、公共リソースも同様に、全体として使われることもあれば、リソースの一部として使われることもあります。人間はオペレーティング システムのプロセスに相当し、映画館の各座席は共有リソースのごく一部に相当します。人が座席を予約するために映画のチケットを購入することは、映画のチケットを購入するプロセスに相当します。セマフォを使用して共有リソースを予約します。セマフォのアプリケーションが失敗した場合、セマフォはプロセスを許可しません。共有リソースを保護するには、共有リソースにアクセスします。セマフォの本質はカウンタです。セマフォを申請するには、カウンタをデクリメントしてパブリック リソースを予約する必要があります。パブリック リソースを解放した後、セマフォを追加して追加する必要があります。パブリック リソースにアクセスする前に、すべてのプロセスがシグナルを申請する必要がありますセマフォを申請する前提は、すべてのプロセスが最初に同じセマフォを参照する必要があるため、セマフォ自体がパブリック リソースであると推測できます。パブリック リソースであるため、データ セキュリティの問題があるはずです。また、保証する必要があります 自分自身のデータが安全であるため、セマフォの ++ および - 操作もアトミックでなければなりません セマフォの増加を p 操作と呼び、セマフォの減少を v 操作と呼びます。セマフォの初期値が 1 の場合、それをバイナリ セマフォと呼びます。これは、リソースにアクセスできないか、自分だけがアクセスできることを意味するため、相互排他的セマフォとも呼ばれます。ここで皆さんに注意していただきたいのは、セマフォのアプリケーションが成功したからといって、将来的に共有リソースにアクセスできるようになるわけではないということです。セマフォのアプリケーションが成功したということは、共有リソースの中に自分に属するリソースが存在する可能性があることを意味するだけです。これは高速鉄道の切符を買うときと同じで、まず切符の購入が成功し、しばらくして切符が発券されると、自分がどの車両のどの位置に座っていたのかが分かります。セマフォはチケットの購入が成功したことと同等ですが、どのリソースにアクセスすればよいのかまだわからないため、この部分の作業はプログラマに任せる必要があります。

セマフォ関連機能

まず、semget 関数を見てみましょう:
ここに画像の説明を挿入します
この関数の機能は、すべてのプロセスで認識できるセマフォを適用することです。最初のパラメーターはキーであり、2 番目のパラメーターは、セマフォがいくつあるかを示すために使用されます。適用する場合セマフォが 10 個ある場合、第 2 パラメータに 10 を渡します semflg は前の識別ビットです 適用が成功すると、セマフォ セットの識別子が返されます 適用が失敗した場合は、 -
ここに画像の説明を挿入します
1 が返されます。次のステップは、最初のセマフォ制御関数です。
ここに画像の説明を挿入します
ははカウンタであるため、対応するカウンタの加算および減算の操作が必要です:
ここに画像の説明を挿入します
最初のパラメータは、どのセマフォを操作するかを示し、2 番目のパラメータは構造体です。この構造体には 3 つのパラメータがあります: 最初のパラメータは、
ここに画像の説明を挿入します
どのセマフォを操作するかを示します複数のセマフォの間で有効であると仮定します。セマフォが 1 つだけある場合、このパラメーターによって渡される値は 0 です。2 番目のパラメーターは、実行する操作を示します。このパラメーターに設定できる値は 1 または -1 です。値が 1 の場合、指定されたセマフォが追加されます。値が -1 の場合、指定されたセマフォを減らすことを意味します。3 番目のオプションは直接 0 に設定できます。これが 2 番目のパラメーターの役割です。3 番目のパラメーターは、その方法を示します多くのセマフォ操作。一度に 10 個のセマフォを操作したい場合は、3 番目のパラメーターに 10 を渡し、2 番目のパラメーターに構造体配列を渡します。これはセマフォに関連する操作です。ここでは後で実行します。マルチスレッド保護については、引き続き皆様に説明していきます。

IPC リソースの編成方法

共有メモリには独自の属性があるため、共有メモリを記述するための対応する構造があります。shmctl を介して表示できます: ここには 2 つの構造があります。2 つの構造は共同で共有メモリ
ここに画像の説明を挿入します
の属性を記述します。共有メモリと同様に、メッセージがあります。ペアも共有リソースなので、リソースのこの部分を記述するための対応する構造体も存在します。その後、msgctl 関数を使用してそれを表示できます。リソースのプロパティも 2 つの構造体によって一緒に記述されていることがわかります
ここに画像の説明を挿入します
。セマフォについて学びました。セマフォの本質はカウンタと共有リソースであるため、そのプロパティを記述するための対応する構造も持っています。その後、semctl を使用してそれを表示できます。2 つの構造があることもわかりますよく
ここに画像の説明を挿入します
見ると、これら 3 つの共有リソースを記述する 2 つの構造体のうち、ipc_perm という名前の構造体があり、もう 1 つの構造体の最初のフィールドが ipc_perm. 構造体オブジェクトであることがわかります。 System V 標準のプロセス間通信です。いわゆる標準は誰もが使用する方法です。インターフェイスの設計とデータ構造の設計は標準に準拠する必要があります。オペレーティング システムはそれをどのように管理しますか? これらのデータはどうなりますか? ? たとえば、5 つの共有メモリ、次に 3 つのメッセージ キュー、最後に 4 つのセマフォを申請した場合、オペレーティング システムはこれらのリソースをどのように管理しますか? まず、各共有リソースの構造の最初のフィールドが ipc_perm であり、データの一意性を保証するためにキー値を記録するフィールドが ipc_perm 構造内にあることがわかります。さまざまな共有
ここに画像の説明を挿入します
リソースを管理する ipc_perm の配列を作成するだけです (例: 以下の図):
ここに画像の説明を挿入します
共有リソースを申請しない場合、オペレーティング システムは対応する構造を作成します。たとえば、共有メモリを申請すると、メッセージ キュー、セマフォ、オペレーティング システム 対応する構造体オブジェクトが作成されます (下の図のように)。
ここに画像の説明を挿入します
これら 3 つの構造体の最初の要素は ipc_perm であるため、配列内の要素が次の最初のメンバーを指すようにすることができます。 3 つの構造:
ここに画像の説明を挿入します
構造体の最初の要素のアドレスは構造体のアドレスとまったく同じですが、アドレスの型が異なるため、対応する属性にアクセスしたい場合は、配列を通じて対応するアドレスを取得できます。次に、アドレスの属性を変更するだけです。たとえば、配列の最初の要素が共有メモリ構造を指している場合、配列の次のテーブルを通じて特定のアドレスにアクセスし、強制転送を直接実行できます。perms[0]構造内の他の要素にアクセスします(struct shmid_ds*)perms[0]: このメソッドを使用すると、さまざまな構造リソースを配列に保存できるため、ここでまだ少し混乱するかもしれませんが、コンピュータは以下の表のどの要素にどのリソースが格納されているかをどのようにして知るのでしょうか。 ?構造はどうですか?したがって、ここでは心配する必要はありません。構造体を作成できます。構造体の最初の要素は、データのタイプを表すために使用される整数です。2 番目のパラメータは、ipc_perm ポインタで、構造体の最初の要素を指すために使用されます。データ構造要素、次のコードなど:

struct myIPC
{
    
    
	int type;
	struct ipc_perm*;
}

このようにして、ipc_perm を指すポインターの配列の維持から myIPC の構造体の配列の維持に変更するので、ここでは心配する必要はありません。これを見ると、これについてよく理解しているはずです。これは C++ のポリモーフィズムに似ていますが、間違いではありません。これは C 言語で実装されたポリモーフィズムと同等です。このアイデアは、C++ でポリモーフィズムを実装したときにここから来たのかもしれません。ipc_perm は C++ の基本クラスと、3 つの共有クラスの記述オブジェクトに相当します。リソースは派生クラスと同等です。派生クラスのポインターを使用して派生クラスの最初の要素を指し、強制的な型変換を通じて、派生クラスの他のメンバーやプロパティにアクセスできます。これが IPC の方法です。リソースが整理されています。

おすすめ

転載: blog.csdn.net/qq_68695298/article/details/132818562