2016-09-30 10 views
0

私は、HP-UXからRed Hat Linux(SVr4)へのSystem Vキューを使用するC/C++コードを移植することを義務づけています。Linux System Vメッセージキューの待ち受けリーダー/ライターを見つけるにはどうすればよいですか?

ほとんどのコールは上手く翻訳されていますが、特定のキューで待機中の読者と作成者を検出することに関連して、特定の問題が発生しています。

HPでは、msgctl(IPC_STAT)を使用して、特定のキューに関する詳細を含むmsqid_ds構造体を取得できます。

この構造の詳細の中には、短い値msqid_ds.msg_perm.modeがあります。この値は、ユーザー/グループ/その他のr/w権限を指定するために低い9ビットを使用します。

しかし、HP上で、より高い7ビットは2つのフラグ次のフラグを含む他の状態情報保存:

#define MSG_QWAIT  00001 /* a writer is waiting on qp->msg_cbytes */ 
#define MSG_FWAIT  00002 /* a writer is waiting on msgfp */ 

この一つは、例えば、テストすることができ、(msqid.msg_perm.mode & (MSG_RWAIT | MSG_WWAIT))いずれかの読者が存在するかどうかを確認するために、またはライターはキューでブロックされます。

私はLinuxに移植しているので、この機能は同じではないことは明らかです。これらのフラグの定義は存在せず、msqid_ds.msg_perm.modeの値は上位のビット情報にはっきりと存在しません。

もちろん、これらのキューの読み取り者と書き込み者が維持されるカーネル操作があります。私の希望は、この情報を発見するためにいくつかの操作を呼び出すことができるということです。

答えて

0

私が知る限り、Linuxにはユーザーが直面している情報を入手するための機能はありません。また、POSIXはそのような機能を定義しません(POSIXメッセージキューでさえも)。もちろん、カーネルはメッセージキューの状態を維持する必要がありますが、その情報がユーザランドから照会できる既存のメカニズムはありません。あなたがカーネル用のドライバを書くことを夢中にしていない限り、私はあなたのポートがあなたが望んでいたよりも深い変更を必要とするだろうと考えています。

しかし、それは長期的には必ずしも悪いことではありません。ベンダーの拡張機能ではなく、標準的な機能だけに依存するようにコードを修正すれば、より堅牢でメンテナンス性が高く、移植性が向上します。レガシーコードが何をしようとしているかによっては、影響を受けた領域で全体的に優れたデザインになることさえあります。

たとえば、プログラムが問題の情報を必要としている理由と、それが何をどうするのかを考えてみましょう。私は1つの正当な理由しか見ません。テストは、圧力解放機構の一部としてプロセス/スレッドによって実行されます。キューが多すぎる/大きすぎるメッセージで窒息すると、一部のメッセージが破棄されます。私が考えてきたその他の理由は、ノンブロッキングセンドや受信を使用することによって、悪意のあるか、より良いサービスを提供することができます。あなたのプログラムの理由が後者のグループにあるならば、それがしようとしていることをするためのより良い方法があります。

前述の圧力緩和の目的であっても、プログラムが取得する前にメッセージキューの一時的な状態に関する情報が失われている可能性があることに注意してください。プログラムが収集した情報を処理する前に、ブロックされたすべての送信者が正常に処理され、新しいメッセージ送信の試みがブロックされている可能性があります。それはおそらく理解された制約ですが、それはあなたの圧力救助戦略を知らせるべきです。その場合、少なくとも次の代替手段があります。

  • 送信者がブロックされているかどうかを判断する代わりに、キューの容量があるかどうかを判断します。エンキューされたメッセージの現在の数と最大数の両方を標準struct msqid_dsから判断できます。キューに収容できる最大バイト数を判断することもできますが、現在のエンキューされたバイト数を判断する標準的な方法はありません。

  • (非ブロック送信を使用して)メッセージを送信しようとしてキューがブロックされているかどうかを確認してください。成功した場合は、直ちにメッセージを削除してください。メッセージタイプを使用して、これらのメッセージをアプリケーションの他のメッセージと区別することができます。他の受信者からの協力を得て、メッセージタイプを使用して、他の受信者がこれらのプローブメッセージを受信しないようにすることができます。

+0

私が作業しているケースでは、少なくとも2つの方法で情報を使用します。 最初の情報は純粋に情報です。ユーザーは数十のキューを「一目で」見ることができ、行項目の1つは、少なくとも1つのプロセスが読み取り/書き込み操作でブロックされているかどうかを示します。 第2は、基本的な固定メカニズムです。ユーザーには、キューの内容を切り捨てたり、キューをまとめて削除したりするための基本的な操作がいくつかあります。これらのオプションは、使用されることはめったにありません。ロッカーが存在する場合は禁止されているものもあります。 あなたの結論は、私が得ている印象を強くし、とても感謝しています。 – cyph

+0

ちなみに、正確なLinuxの実装やリリースを特定するのには苦労していますが、Linuxの少なくとも*いくつかのバージョンでは、msqid_dsのwwaitとrwaitのメンバーの一言の情報を見てきました。 例ref:http://www.tldp.org/LDP/lpg/node32.html これはこれがかつてLinuxに存在していたのかどうか不思議ですが、もはやそれはありません。 – cyph

+0

LDPノードは、カーネルの* internal *ヘッダーの1つのバージョンを提示しているようです。対応するユーザー空間ヘッダーのいずれかがあなたが尋ねた情報を提示したかどうかは確信できませんが、ユーザー空間プログラムが直接カーネルメモリにアクセスすることはできないので、決してそれを(*内部カーネルデータ構造へのポインタを介して) –

関連する問題