• ベストアンサー

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

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

  • esi
  • お礼率64% (32/50)

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

  • ベストアンサー
  • 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

  • コンパイラの互換性について

    コンパイラの互換性について教えてください。違うコンパイラで作成したShared Objectを使用するプログラムの動作が不安定になるといったことは考えられますか?考えられるとすれば、どのような理由でそういった事象が発生するのでしょうか? WindowsではMSのコンパイラとBorlandのコンパイラについて。 SolarisではSUNのコンパイラとGNUのコンパイラについて。 Linuxでは異なるバージョンのGNUコンパイラについて。 現状を教えてください。 ここらへんを解説している書籍やURLの紹介も嬉しいです。

  • fortranコンパイラのエラーを英語にしたい

    以下の環境でf90とf77を使っていますが、コンパイル時のエラーが日本語で出てきます。これを英語表示にできないでしょうか。 ・Solaris9 ・コンパイラはForte Developer update1のf90とf77を使用

  • C言語での方向キー入力判定

    C言語でキーの入力判定をするプログラムを作ってい ます。下の例だとeやエンターを押したときは認識できる のに、方向キー↑を押したときはなぜか無反応です。 コンパイラはボーランドでOSはXPでコンパイルした のですが、何がいけなかったのでしょうか? #include <stdio.h> #include <conio.h> #include <windows.h> void check(void){ int key; key = getch(); switch (key){ case 'e': puts("e"); break; case VK_RETURN: puts("ENTER"); break; case VK_UP: puts("UP"); break; } } int main(void) { while(1){ check(); } return 0; }

  • 組み合わせ プログラミング

    c言語についてです os linux コンパイラはgccです long fact2(int n,int m)を作成してfact2(n,m)を使って組み合わせを計算するプログラムを作れという問題で下記のように作りましたが コンパイルできません. エラーメッセージは 2-1.c:14: error: 関数 `fact2' への引数が少なすぎます 2-1.c:14: error: 関数 `fact2' への引数が少なすぎます 2-1.c:14: error: 関数 `fact2' への引数が少なすぎます です 関数のとこが違うと思うですが どうしたらいいのかわかりません それともなにか他のとこが違うのでしょうか? #include <stdio.h> long fact2(int,int); main() { int n, m; long c; printf(" nCm (n>m) \n"); printf("input n m ="); scanf("%d %d",&n, &m); c =fact2(n) / (fact2(m) * fact2(n-m)); printf("%dC%d = %ld\n",n,m,c); } long fact2(int n,int m) { int i; long c=1; for(i=1; i<=n; i++) c*=i; return(c); }

  • POSIXメッセージとは?

    こんにちわ。 私はSolaris8のC++でプログラミングをしている中級者です。 プロセス間通信の方法として、メッセージキューを使っています。 具体的には、キュー作成(msgget)、送信(msgsnd)、受信(msgrcv)、削除(msgctl)等の関数を使っているのですが、これ以外に「POSIXメッセージ」とかいうメッセージがあると聞きました。 SUNのドキュメントで調べてみたのですが、POSIXとは"Potal Operating System Interface for UNIX"で、まあUNIXベースのOSならみんな使えるような関数と解釈しました。この解釈は正しいでしょうか? そして、私が使用しているmsgXXX関数とどのように違って、どのような利点があるのでしょうか? 具体的には、上記のmsgXXXを実現するために、mq_open(), mq_close, mq_send, mq_receiveを使えば良いというだけのことなのでしょうか? POSIXメッセージとは、何か?また、こうやって使うんだよというような参考になるURLをご存じの方がいらっしゃいましたら、教えてくださいませ。

  • 未使用引数の注意文出力を回避するには

    他種CPUの古いCソースをSH版に移植中なのですが、日立SHCコンパイラの オプション -ME でメッセージ出力抑制を解除すると大量の注意文が出力されて対処に 困っています。 その中で、C0012 (I) Unused variable "~" について、関数の取り合い仕様で引数が規定されているが、関数内処理では使われない 場合に注意文の出力を回避したいのですが、何かいい対策案ないでしょうか? int func( int a,int *b ){ return(0); } これまで分かっていることは 1)コンパイラは出荷済み他製品と共通なのでバージョンを上げられない。 2)-NOME=12 の出力抑制オプションは自動変数の未使用も検出しなくなるので不可。   (コンパイラも現状バージョンは番号指定に未対応です) 3)return(0); の後ろに a=0;b=0; と入れるとC0003 (I) Unreachable statementが出る。 4)変数属性の unused はコンパイラが未対応。 対策案の一つとして、関数内に if(a==0){} if(b==0){} を入れるというのがあるのですが、余分な機械語を生成しないか不安で検討中です。

  • JAVAで作成したプログラムは外部からの指示をどうやってうけとるのか?

    このたび、JAVAで、通信関連のプログラム(常駐)をつくることになりました。それで、このプロセスに対して外部からコマンド(終了の指示、何か処理をしなさい等)を発行したいのですが、そのインターフェースが判りません。 OSはSolaris又はLinuxを採用する予定です。C言語で作成した時は、メッセージキュー、シグナル等を使用していたのですが、100% pure JAVAの環境で、このような外部からコマンドを受け付ける仕組みは、作成できるのでしょうか。ご存じの方おりましたら、教えて下さい。

    • ベストアンサー
    • Java
  • メッセージキュー

    WINAPIで、メッセージキューにポストします。 この時の、メッセージキューとは、プログラムのどこにあたりますか? ウインドウプロシージャーの第二引数のUINT uMsg,の部分ですか? MSG構造体のことですか? 教えてください。

  • x86用Sun Studio12におけるコンパイラのバグでしょうか?

    今、x86用Solaris10にStudio12をインストールして、C++のプログラムを作ったのですが、仮想継承を定義すると正常な動作をしません。 調べたところ、どうやら基底クラスから継承している関数のポインタが基底クラスとそれを呼び出す派生クラスでずれてしまっていることが原因のようでした。 試しにsparc用Solaris10+Studio12でも同じプログラムを動作させ、調査したところ、こちらは上述の現象もなく、正常に動作しています。 これはx86用Studio12についているコンパイラのバグなのでしょうか? また、サポート契約なしに、このバグ報告をSunに行う方法がありましたら教えてください(サイト(http://jp.sun.com/)を見ましたが該当事象に対するパッチ及びバグ報告方法について記載が見つかりませんでした。 どなたかご教示いただけないでしょうか。

  • C++で他のファイルの関数の引数を引きだす方法

    C++初心者です。 あるCプログラムに関数: testFunction(const char x[ ], int a, int b, int c)があり、 この関数はchar y[ ]を戻り値として返します。 次の段階で、別のC++を作成し、その中で、上記testFunctionを呼び出し、 使用している引数を引き出して以降のプログラムで使用する仕様のプログラムを組んでいます。 他のファイルに存在する関数を呼び出す方法は、 std::cout << testFunction(x[], a, b, c) << std::endl; ではないかと思っているのですが、ここから先が進まず困っている状況です。 戻り値だけではなく、引数も呼び出すことは可能でしょうか。 可能であれば、どのようにして呼び出すことができるのでしょうか。 アドバイスをお願いいたします。

専門家に質問してみよう