0

私は、System V キューを使用する C/C++ コードを HP-UX から Red Hat Linux (SVr4) に移植する任務を負っています。

ほとんどの呼び出しは問題なく変換されましたが、特定のキューで待機中のリーダーとライターを検出することに関連する特定の問題が 1 つあります。

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

この構造体の詳細には short 値msqid_ds.msg_perm.modeがあり、下位 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は明らかに上位ビット情報がありません。

しかし、確かに、これらのキューのリーダーとライターが維持されるカーネル操作があります。この情報を発見するために何らかの操作を呼び出すことができることを願っています。

4

1 に答える 1

0

私が判断できる限り、Linux には、目的の情報を取得するためのユーザー向けの機能がありません。また、POSIX ではそのような機能は定義されていません ( POSIXメッセージ キューについても定義されていません)。もちろん、カーネルがメッセージ キューの状態を維持する必要があるのはあなたの言うとおりですが、ユーザーランドからその情報を照会できる既存のメカニズムは見当たりません。カーネル用のドライバーを書きたくないのであれば、あなたの移植には、あなたが望んでいたよりも深い変更が必要になると思います。

しかし、それは長期的には必ずしも悪いことではありません。ベンダーの拡張機能ではなく、標準機能のみに依存するようにコードを適応させることで、コードの堅牢性、保守性、および移植性が向上することが期待できます。レガシ コードが何をしようとしているのかによっては、影響を受ける領域で全体的に優れた設計になることさえあります。

たとえば、プログラムが問題の情報を必要とする理由と、それをどうするかを考えてみてください。正当な理由は 1 つだけです。テストは圧力解放メカニズムの一部としてプロセス / スレッドによって実行され、キューが多すぎる / 大きすぎるメッセージで詰まると一部のメッセージが破棄されます。私が考えた他のすべての理由は、考えが間違っているか、非ブロッキングの送信および/または受信を使用することでより適切に処理されます。プログラムの理由が後者のグループにある場合は、実行しようとしていることを実行するためのより良い方法があります。

前述のプレッシャーの軽減が目的であっても、メッセージ キューの一時的な状態について取得した情報は、プログラムが取得する前に古くなる可能性があることに注意してください。ブロックされたすべての送信者は、収集した情報に基づいてプログラムが動作する前に正常に処理を進めた可能性があり、新しいメッセージの送信試行がブロックされた可能性があります。これはおそらく理解されている制約ですが、プレッシャー軽減戦略に役立つはずです。その場合、少なくとも次の代替手段があります。

  • 送信者がブロックされているかどうかを判断する代わりに、キューが容量に達しているかどうかを判断します。struct msqid_dsエンキューされたメッセージの現在の数と最大数の両方を標準から判断できます。キューが収容できる最大バイト数を決定することもできますが、現在エンキューされているバイト数を決定する標準的な方法はありません。(ただし、ベンダー拡張機能に夢中になっている場合は、Linux 固有の方法があります。)

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

于 2016-10-03T15:20:26.403 に答える