7

同じワークステーション上の 2 つのアプリケーション (プロセス) から使用したい単一の HW インターフェイスがあります。HW は 1 回の初期化呼び出しを必要とし、いずれかのアプリが (同じライブラリ内の) 同じ関数を使用して、HW で多くのトランザクションを実行します。

したがって、各アプリは次のように動作する必要があります。

main()
    // I don't know if another app already init'ed the HW
    ret = hw_init_lock(non-blocking)

    if ret = OK
        // no one else has done this, I have to
        init_hw()
    else
       //someone else has already init'ed the HW, I gotta make sure it stays that way
       //as long as I'm alive
       increment_hw_init_ref_counter()

    hw_trans_lock(blocking)
    hw_trans()
    hw_trans_unlock()
    ....

    //exit app, uninit hw if we are last out
    ret = decrement_hw_init_ref_counter()
    if ret == 0
        uninit_hw()

    exit(0)

2 つのアプリケーション間で共有されるロックおよび参照カウント呼び出しで使用できるメカニズムは何ですか? 名前付きパイプ、つまり mkfifo() を考えています。

4

6 に答える 6

9

POSIX セマフォが最適です。プロセス間で同じセマフォを共有したいので、名前付きセマフォを使用する必要があります。

名前付きセマフォは、/somename という形式の名前で識別されます。同じ名前を sem_open(3) に渡すことにより、2 つのプロセスが同じ名前付きセマフォで動作できます。

于 2008-10-30T02:02:13.073 に答える
4

セマフォとミューテックス/条件変数は、スレッド間またはプロセス間での使用に適した、優れた非常に高性能なプリミティブです。

これらはすべて、共有メモリに対して実行されるテスト アンド セットまたはその他のアトミック操作のアイデア (および通常は現実) に基づいています。

プロセスをネットワーク経由で分散することを期待している場合、セマフォとミューテックスは適していない可能性があります。これらは 1 台のマシンでしか機能しません。パイプとソケットは、より一般的にネットワーク拡張可能です。

ミューテックス、条件変数、およびセマフォの簡単な要約:

ミューテックス

ミューテックスは、ロックまたはロック解除できるプリミティブです。ロックしたプロセス/スレッドは、ロックを解除する必要があります。この所有権の側面により、オペレーティング システムは、優先度の継承や優先度上限プロトコル (優先度の逆転を回避するため) などの興味深い最適化を適用できます。 ただし、ミューテックスにはカウントが関連付けられていません。一般に、すでにロックされているミューテックスをロックすることはできず、「2回ロックされた」というメモリを保持できません(これを許可する拡張機能がいくつかあると思いますが、どこでも利用できるわけではありません)

条件変数

ミューテックスは、MUTual EXclusion に最適です。しかし、相互排除しているオブジェクトに関連付けられた条件でブロックする必要がある場合はどうでしょうか? これには、条件変数 (CV) を使用します。CV はミューテックスに関連付けられています。たとえば、プロセスがアクセスしたい入力データのキューがあるとします。ミューテックスを取得して、干渉を恐れずにキューを確認できるようにします。ただし、キューが空であることを検出し、何かがキューに入るのを待ちたいと考えています。したがって、「キューが空ではない」条件変数で待機します。ここで興味深いのは、CV がミューテックスに関連付けられているため、ミューテックスが自動的に再取得されることです。条件変数が通知されると。したがって、プロセスが CV を待機した後にウェイクアップすると、プロセスは再びキューに排他的にアクセスできることを認識します。わからないのは、キューに実際に何かがあるかどうかです-おそらく2つのプロセスがCVで待機していました-1つが入ってきました-そして、最初の優先度が入り、2番目のものが目覚める前に「もの」をキューから外しました。したがって、履歴書を使用するときはいつでも、次のように条件を再確認する必要があります。

mutex_enter(m);
while (! condition) {
   cond_wait(m, c); // drop mutex lock;  wait on cv;  reacquire mutex
}
//processing related to condition
mutex_exit(m);

セマフォ

OK、それはミューテックスと条件変数です。セマフォはより単純です。これらは、任意のプロセスで増減できます。それらにはメモリがあり、カウントされるため、それらを使用して、条件がいくつ発生したかを判断できます。条件変数ではそうではありません。また、セマフォはあるプロセスによってデクリメントされ、別のプロセスによってインクリメントされる可能性があるため、所有権の側面を持たないため、優先順位の継承や優先順位の逆転を回避することはできません。

最後に、これらのメカニズムはすべて、効率的な実装のために共有メモリを必要とします。これで問題ないかもしれませんが、アプリケーションが最終的に配布される可能性があると思われる場合は、ミューテックス、条件変数、およびセマフォが適していない可能性があることに注意してください。パイプとソケットは、オーバーヘッドがはるかに高くなりますが、ネットワーク上でかなり簡単に拡張できる可能性があります。

于 2008-10-30T06:09:24.023 に答える
2

必要なセマフォ数は 1 つだけなので、ミューテックスで十分です。

于 2008-10-30T01:14:39.470 に答える
2

POSIX セマフォを使用します。

于 2008-10-30T00:39:57.280 に答える
1

私はそれを仮定します

...それは 2 つのアプリケーション間で共有されますか?

これら 2 つを別々のプロセスとして実行することを意味しますか? そうではなく、単一のプロセスとして (複数のスレッドで) 実行されている場合は、セマフォとミューテックスの提案が最良の選択肢であり、非常に簡単です。

答えは、このハードウェアにどのようにアクセスしているかによって異なります。たとえば、ファイルを介して公開されている場合は、通常のファイル ロックを使用できます。

ただし、2 つのプロセス間でハードウェアへのアクセスを同期しようとしている場合は、別の問題です。最初に言うことは、可能であれば、ハードウェアへのアクセスを単一のプロセスが担当する方が同期が簡単になるということです。このモデルでは、ハードウェアのサーバーとして機能する 1 つのプロセスがあり、他のプロセスからの要求を受け入れ、代わりに読み取りと書き込みを実行します。ほぼすべての形式のプロセス間通信が適していますが、簡単にするために、適切なデータ構造 (たとえば、読み取り操作か書き込み操作かを示すフラグ、ベース アドレスからのオフセット) を備えたメッセージ キュー (リンク) のようなものが適している場合があります。ハードウェア、バイト数、バッファ (書き込みの場合))

すべてのハードウェアへの直接アクセスを 1 つのプロセスに配置することが適切でない場合は、適切な同期スキームを使用する必要があります。ファイルロックの使用(および基本的なミューテックススキームの実装)、または名前付きセマフォの使用(albertbが提案したように)を調査します

于 2008-10-30T02:05:43.457 に答える