プロセスがメッセージを送受信できるようにするには、msgget(2) を使用して待ち行列を初期化する必要があります。待ち行列の所有者または作成者は msgctl(2) を使用して、所有権またはアクセス権を変更できます。アクセス権を持つプロセスは msgctl(2) を使用して、操作を制御できます。
IPC メッセージを使用すると、プロセスはメッセージを送受信し、メッセージを任意の順序で処理待ち行列に入れることができます。パイプで使用されるファイルバイトストリームのモデルによるデータフローとは異なり、IPC メッセージでは長さが明示されます。
メッセージには特定のタイプを割り当てることができます。このため、サーバープロセスはクライアントプロセス ID をメッセージタイプとして使用することによって、その待ち行列上のクライアント間にメッセージトラフィックを振り向けることができます。単一メッセージトランザクションでは、複数のサーバープロセスは、共有メッセージ待ち行列に送られるトランザクション群に対して、並行して働くことができます。
メッセージを送受信する操作は、それぞれ msgsnd(2) と msgrcv(2) によって実行されます。メッセージが送信されると、そのテキストがメッセージ待ち行列にコピーされます。msgsnd(2) と msgrcv(2) は、ブロック操作としても非ブロック操作としても実行できます。ブロックされたメッセージ操作は、次の条件のどれかが生じるまで中断されます。
呼び出しが成功した。
プロセスがシグナルを受信した。
待ち行列が削除された。
msgget(2) は、新しいメッセージ待ち行列を初期化します。また、キー引数に対応する待ち行列のメッセージ待ち行列 ID (msqid) を返すこともできます。msgflg 引数として渡される値は、待ち行列アクセス権と制御フラグを設定する 8 進数の整数である必要があります。
MSGMNI カーネル構成オプションは、カーネルがサポートする固有のメッセージ待ち行列の最大数を指定します。この制限を超えると、msgget(2) 関数は失敗します。
次のコードに、msgget(2) の使用例を示します。
#include <sys/ipc.h> #include <sys/msg.h> ... key_t key; /* key to be passed to msgget() */ int msgflg, /* msgflg to be passed to msgget() */ msqid; /* return value from msgget() */ ... key = ... msgflg = ... if ((msqid = msgget(key, msgflg)) == -1) { perror("msgget: msgget failed"); exit(1); } else (void) fprintf(stderr, "msgget succeeded"); ...
msgctl(2) は、メッセージ待ち行列のアクセス権やその他の特性を変更します。msgid 引数は、既存のメッセージ待ち行列の ID である必要があります。cmd 引数は、次のいずれか 1 つです。
待ち行列の状態の情報を buf が指すデータ構造体に入れます。この呼び出しを行うには、プロセスが読み取り権を持つ必要があります。
所有者のユーザー ID とグループ ID、アクセス権、およびメッセージ待ち行列の大きさ (バイト数) を設定します。この呼び出しを行うには、プロセスが所有者、作成者、またはスーパーユーザーの有効なユーザー ID を持つ必要があります。
次のコードに、さまざまなフラグをすべて指定した msgctl(2) の使用例を示します。
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> ... if (msgctl(msqid, IPC_STAT, &buf) == -1) { perror("msgctl: msgctl failed"); exit(1); } ... if (msgctl(msqid, IPC_SET, &buf) == –1) { perror("msgctl: msgctl failed"); exit(1); } ...
msgsnd(2) と msgrcv(2) は、それぞれメッセージを送信および受信します。msgid 引数は、既存のメッセージ待ち行列の ID である必要があります。msgp 引数は、メッセージのタイプとテキストを含む構造体へのポインタです。msgsz 引数は、メッセージの長さをバイト数で指定します。msgflg 引数は、さまざまな制御フラグを渡します。
次のコードに、msgsnd(2) と msgrcv(2) の使用例を示します。
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> ... int msgflg; /* message flags for the operation */ struct msgbuf *msgp; /* pointer to the message buffer */ size_t msgsz; /* message size */ size_t maxmsgsize; /* maximum message size */ long msgtyp; /* desired message type */ int msqid /* message queue ID to be used */ ... msgp = malloc(sizeof(struct msgbuf) – sizeof (msgp–>mtext) + maxmsgsz); if (msgp == NULL) { (void) fprintf(stderr, "msgop: %s %ld byte messages.\n", "could not allocate message buffer for", maxmsgsz); exit(1); ... msgsz = ... msgflg = ... if (msgsnd(msqid, msgp, msgsz, msgflg) == –1) perror("msgop: msgsnd failed"); ... msgsz = ... msgtyp = first_on_queue; msgflg = ... if (rtrn = msgrcv(msqid, msgp, msgsz, msgtyp, msgflg) == –1) perror("msgop: msgrcv failed"); ...