System V メッセージキュー
System V メッセージキューは、メッセージキュー識別子で識別される。カーネルはシステム内のすべてのメッセージキューに対して、その情報を
struct msqid_ds { struct ipc_perm msg_perm; /* 読み書き許可ビット */ struct msg *msg_first; /* キュー上の先頭のメッセージへのポインタ */ struct msg msg_last; /* キュー上の最後のメッセージへのポインタ */ msglen_t msg_cbytes; /* キュー上のバイト数 */ msgqnum_t msg_qnum; /* キュー上のメッセージ数 */ msglen_t msg_qbytes; /* 最大バイト数 */ pid_t msg_lspid; /* 最後のmsgsnd()を行ったプロセスのID */ pid_t msg_lrpid; /* 最後のmsgrcv()を行ったプロセスのID */ time_t msg_stime; /* 最後のmsgsnd()の時刻 */ time_t msg_ctime; /* 最後のmsgctl()の時刻 */ };
msgget関数
#include <sys/msg.h> int msgget(key_t key, int oflag); 戻り値:成功なら非負の識別子、エラーなら-1
引数keyには、ftokが返した値か、IPC_PRIVATE定数を指定できる。
oflagは、読み書き許可ビット。IPC_CREATか、IPC_CREAT | IPC_EXCL。
新しいメッセージキューが加算されると、mqqid_ds構造体のメンバ
初期化されるメンバ | 初期化される値 |
msg_perm.uid | 実効ユーザID |
msg_perm.cuid | 実効ユーザID |
msg_perm.gid | 実効グループID |
msg_perm.cgid | 実効グループID |
msg_perm.mode | oflag中の読み書きビット |
msg_qnum | ゼロ |
msg_lspid | ゼロ |
msg_lrpid | ゼロ |
msg_stime | ゼロ |
msg_rtime | ゼロ |
msg_ctime | 初期化の時刻 |
msg_qbytes | システムの限界値 |
msgsnd関数
msggetでオープンしたメッセージキューには、msgsndを用いてメッセージを置くことができる。#include <sys/msg.h> int msgsnd(int msqid, const void *ptr, size_t length, int flag); 戻り値:成功なら0、エラーなら-1
msqidは、msggetが返した識別子。ptrは、
struct msgbuf { long mtype; /* メッセージタイプ (ゼロ以上) */ char mtext[1]; /* メッセージデータ */ };
しかし、1バイトのメッセージを用いることは適切ではないため、このmsgbuf構造体を通常用いない。
大半のアプリケーションでは、独自のメッセージ構造体を定義している。
flag引数は、ゼロまたはIPC_NOWAIT。このフラグは、msgsndの呼び出しを非ブロッキングにする。
msgrcv関数
#include <sys/msg.h> ssize_t msgrcv(int msqid, void *ptr, size_t length, long type, int flag); 戻り値:成功ならバッファに読み込まれたバイト数、エラーなら-1
typeは、キュー上のどのメッセージを取り出すかを指定する。
キューの先頭(キューの最も古い)のメッセージが返される。
そのtypeを持つ先頭のメッセージが返される。
typeの絶対値と等しいかまたは小さなタイプを持つメッセージの中で、最も小さなタイプを持つ最初のメッセージが返される。
flag引数は、指定したメッセージがキュー上にない場合の動作を指定する。
1.供給したタイプのメッセージが置かれた場合
2.msqidで識別されるメッセージキューが、システムから削除された場合(この場合は、EIDRMエラーが返される。)
3.呼び出したスレッドが、捕捉したシグナルによって割り込まれた場合(この場合はEINTRエラーが返される。)
flag引数で、MSG_NOERRORビットを指定すると、受信したメッセージのデータ部の大きさがlength引数よりも大きくても、エラーを返さずにデータを切り捨てることを指示する。MSG_NOERRORを指定していない場合は、メッセージの全長がlengthを越えるならばE2BIGエラーが返される。
msgctl関数
msgctlを用いて、メッセージキューに対して種々の操作を施すことが出来る。#include <sys/msg.h> int msgctl(int msqid, int cmd, struct msqid_ds *buff); 戻り値:成功なら0、エラーなら-1
cmdに与えるコマンド
IPC_RMID | msqidで指定されるメッセージキューを、システムから削除する。 |
IPC_SET | msqid_ds構造体のmsg_perm.uid, msg_perm.gid, msg_perm.mode, msg_qbytesメンバを、buff引数が指す構造体の対応するメンバの値に設定する |
IPC_STAT | 指定されたメッセージキューのmsqid_ds構造体を、buff引数を通して呼び出し側に返す |