• ベストアンサー

msgget()で指定するkey値について

solaris9上でメッセージキューを使用したCプログラム を作成するのですがmsgget関数で不明点があります。 尚、コンパイラはSUNのForte Cです。 int msgget(key_t key, int msgflg); 第一引数のkeyに指定する値ですが、サーバ内の開発 プログラム全体で重複しないようにするのは当然かと 思いますが、OSで予約されている番号とかあるので しょうか? 例えば  0~999:OSで使用  1000番以降:ユーザアプリで利用可 OSでもメッセージキューとか使用していると思うので 適当な番号を取ったらダメだろうなと思って色々調べた のですが解決する事ができませんでした。 すみませんがご教授の程よろしくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.1

通常、keyを生成する場合は、以下の手順をとります。 1.ftok関数でkey値を取得する。 key値=ftok(p1,p2); p1は、ある基準となるファイルの絶対パス名(以下基準ファイルと略記) p2は1~255の任意の数値 上記により、同一の基準ファイルに同一のP2を与えた場合は、本システム内でかち合わないユニークなキー値 を発生させることをOSが保証します。 2.従って、以下のようにします。 P1へ基準ファイルの絶対パス名をセット key1=ftok(p1,1);・・・メッセージキュー1用 key2=ftok(p1,2);・・・メッセージキュー2用(以下同様、但しMAX255迄) 但し、key1,key2が-1の場合は、ftokのエラーのため、使用不可(このチェックを入れて下さい) また、この基準ファイルは、絶対に更新しないで下さい。(タイムスタンプが変わると同一のキー値が得られません)又、このファイルを毎回かならず使用して下さ い。 3.あとはこのkey1,key2・・を使ってmsggetを行って下さい。

esi
質問者

補足

早速のご回答ありがとうございます。 この基準ファイルですが、キー値を生成する為だけに 作成するファイルと考えてよろしいでしょうか? touch等で中身が無いファイルを作成して、テスト プログラムを作成してテストしてみましたところ 上記key1、key2で別のキー値がちゃんと拾えました。 現在運用中のシステムでmsgget()を使用している プログラムがあるのですが、なんとkey値を固定で define切って指定しており、ftokで取得している 形跡はまったくありませんでした。 作成者がいないので、なんでftokを使用しなかった のは不明ですが、これは明らかに危険な使用方法 かと思いますが、これについてご意見頂けませんで しょうか?

すると、全ての回答が全文表示されます。

その他の回答 (3)

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.4

#2です。#3の方の言われるようにftokで取得したkeyの一意性は保証されないみたいですね。一意性をOSが保証すると書きましたが、誤りでした。お詫びして訂正します。

esi
質問者

お礼

返答がおそくなり申し訳ございません。 大変助かりました。 ご回答ありがとうございました。

すると、全ての回答が全文表示されます。
  • chipizou
  • ベストアンサー率44% (8/18)
回答No.3

OSにもよると思いますが、ftokで生成されたキーの一意性は保証されません。 例えば、Solarisやlinuxではftokの第一引数で指定されたファイルのi-nodeの何ビットかと第2引数で指定された値の論理和をとって値を生成しているだけです。 全てのi-nodeを使用してキーを生成していれば問題ないのですが、一部しか使用していないため、同じキーを生成してしまう場合があります。 対策として、最初のmsggetでIPC資源の獲得を行う際に、存在していれば、エラーとするモードで獲得し、その獲得に用いたキーを通常のファイルなどで他のプロセスに引き渡すという方法が考えられます。

esi
質問者

お礼

返答がおそくなり申し訳ございません。 大変助かりました。 ご回答ありがとうございました。

esi
質問者

補足

ftokのオンラインマニュアルにて、最後の方に 補足で保証されないようなことが書いてあった ので気になっていました。 多少処理が煩雑になりますが、ご提示頂きました 対策にてそのファイルから取得できたキーを 受信側でも使用する方法で検討しようと思います。 ご回答ありがとうございました。

すると、全ての回答が全文表示されます。
  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.2

>この基準ファイルですが、キー値を生成する為だけに 作成するファイルと考えてよろしいでしょうか? はい、その通りです。通常は、そのための専用の空のファイルを作成します。(決して他の用途には使用しないで下さい。又、更新しないで下さい。削除後、再度、作成すると別のキー値が取得されるようになります) >作成者がいないので、なんでftokを使用しなかった のは不明ですが、これは明らかに危険な使用方法 かと思いますが、これについてご意見頂けませんで しょうか? 頭のいたい問題ですね。 対策としては、以下の案が考えられます。 1案.そのプログラムを#defineの使用をやめて、ftok関数を使用するように変える。 但し、現在、運用されているので、変更後、十分な試験が必要です。又、現行のプログラムが簡単に変更できることが前提です。 2案.現行のままにしておく。但し、そうすると、今回ftokで取得したkey値が、#defineで定義されている値と、万が一かち合う可能性がある。ftokを使用する限りでは、ユニークな値を生成することをOSは保証しますが、#defineで定義されている値とかち合わないことは、(当たり前の話ですが)保証できません。万が一、かち合った場合の対策は、しておいた方がよいでしょう。(対策は、かちあったら、ログをかいてアボート、又は、かちあわなくなるまで、再取得するの何れかでしょう) 3案.これから作るプログラムは、現行のプログラムのdefine値とかち合わない値を#defineして使用する。(ftokは使用しない) 但し、これは、最初の質問に戻った状態になります。 OSがこの#defineの値を使用していないこと。他のプログラムが、使用していないことの裏付けをとる必要があります。(OSがどの範囲のkeyを使用するかは私は判りません。というよりは、OSは何番以下もしくは何番以上を使用することを保証してないように思われます。)又、仮にOSが使用する範囲が、判ったとしても、他のアプリ(今後、作り込むアプリも含めて)とかち合わないことを保証する場合は、#defineを1つのソースにまとめて、一元的に管理する必要があります。 上記のことより、私なら、1案ー>2案ー>3案の順に、対策を施すでしょう。

esi
質問者

補足

丁寧なご回答ありがとうございます。 1案ー>2案ー>3案の順で相談してみようと 思います。 chipizouさんのご回答にもありますように、 かちあった時の方法だけ明確にして対処を検討 します。 ご回答ありがとうございました。

すると、全ての回答が全文表示されます。

関連するQ&A