※2017/05/25 22:25 修正あり
Linuxのメッセージキューは、まずはサンプルを動かすことにした。
いつものように、LinuxといいつつWindows10のBash on Ubuntu on Windows(以下 BoW)だ。
が・・・コンパイルは通るものの、msgget()でエラーになる。
Function not implemented
嫌な予感は的中した。
System V IPC is missing · Issue #1016 · Microsoft/BashOnWindows
Creators Updateでセマフォと共有メモリは対応したけど、メッセージキューはbacklogと書いてあるから、まだ残ってるという意味なのかな。
まあ、何でもかんでも期待しちゃいかんだろう。
VMに入っているUbuntu環境に持っていくと、進んだ。
が、msgsnd()でInvalid argumentが出てしまう。
Man page of MSGOP
msgsnd()がEINVALを返すのは、以下のどれか。
- msqid が不適切な値
- mtype が正の値でない
- msgsz が不適切な値 (0 以下か、システムで決まる値 MSGMAX よりも大きい値)
msqidはチェックしているし、mtypeも正の値を代入している。
ということは、3番のmsgszだ。
サンプルでは、こういう構造体になっていた。
struct {
long mtype
char mtext[BUFSIZ];
};
このBUFSIZは、8192だった。
だから、sizeofすると、たぶん8196・・・違った、8200だった。
8byteアラインなのね。
ではMSGMAXは?
これはマクロ値にはなっていないようだったが、Man pageの下の方に書いてあった。
MSGMAX
メッセージのテキストの最大サイズ: 8192 バイト (Linux では、この制限値は /proc/sys/kernel/msgmax 経由で読み出したり変更したりできる)。
うーん、ここだけ読むとメッセージのテキストの最大サイズだから使ってもよさそうなのだけど、msgszのが超えたらいかんと書いてある方が強いのだろう。
というわけで、うちの環境ではmtextが8184までOKで、8185からInvalid argumentになった。
sizeofはマクロに入れられないので、
struct {
long mtype;
char mtext[SZ_BUF];
};
#if 8 + SZ_BUF > 8182
#error !!!
#endif
みたいにして判定させるのが良いかも。
※追記
あれからいくつか見てみたが、msgsnd()に指定するサイズとして、sizeof(構造体)ではなく、sizeof(構造体) - sizeof(long)、としているサイトが見られた。
ま、まさか・・・。
もう一度説明を見直すと、msgsnd()のサイズとして指定するのは、struct msgbufではなく、mtextに相当するサイズ(msgsz)と書いてあるではないか!
私はmsgsnd()で構造体のサイズを指定していたのだが、それではダメだ。
そして、アラインメントもあるので、sizeof(long)を引くのも正しくなさそうな感じがする。
ここは、mtextに相当するサイズをマクロで指定するのがよいのかもしれん。
ふっ、まだまだ私も青いのぅ。。。
タイトルは間違っていないものの、動作検証をしていないから、後日やろう。
0 件のコメント:
コメントを投稿
コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。
注: コメントを投稿できるのは、このブログのメンバーだけです。