Linuxカーネルでは、メッセージキューはどのように実装されていますか?

Linuxカーネルでは、メッセージキューはどのように実装されていますか?

Linuxカーネルでメッセージキューがどのように実装されるかを知りたいです。

答え1

Linuxカーネル(2.6)は2つのメッセージキューを実装しています。 (
実装はリンクリストを使用して行われ、先入れ先出しの原則に厳密に従わないため、「メッセージリスト」の代わりに)

システムV IPCメッセージ

System Vのメッセージキュー。

メッセージを送信するためにプロセスを呼び出すことができますmsgsnd()。彼は、着信メッセージキューのIPC識別子、メッセージサイズ、およびメッセージタイプとテキストを含むメッセージ構造を渡す必要があります。

一方、プロセス呼び出しはmsgrcv()メッセージを受け取り、メッセージキューのIPC識別子、メッセージを保存する場所、サイズ、および値を渡します。ティー

ティーキューから返されるメッセージを指定します。正の値は、タイプが次の最初のメッセージを表します。ティー戻り値、負の値はタイプと同じ最後のメッセージを返します。ティー0 はキューの最初のメッセージを返します。

これらの関数は次に定義されています。include/linux/msg.hそして実装ipc/msg.c

メッセージサイズ(最大)、メッセージの総数(mni)、およびキュー内のすべてのメッセージの合計サイズ(mnb)は、次のように制限されます。

$ sysctl kernel.msg{max,mni,mnb}
kernel.msgmax = 8192
kernel.msgmni = 1655
kernel.msgmnb = 16384

上記の出力はUbuntu 10.10システムの出力であり、デフォルト値は次のように定義されています。メッセージ.h

以前のSystem Vメッセージキューの内容のより驚くべき説明ここ

POSIXメッセージキュー

POSIX 標準は、System V IPC メッセージキューに基づいてメッセージキューメカニズムを定義し、いくつかの機能を拡張します。

  • シンプルなファイルベースのアプリケーションインタフェース
  • サポートメッセージの優先順位
  • 非同期通知のサポート
  • ブロック操作がタイムアウトしました。

バラよりipc/mqueue.c

はい

util-linuxメッセージ・キューを分析および変更するためのいくつかのプログラムが提供されており、POSIX 仕様はいくつかの C 例を提供します。

ipcmk以下を使用してメッセージキューを作成します。通常、ftok()次のC関数を呼び出してこれを行いますmsgget()

$ ipcmk -Q

ipcsorを使って何が起こるのか見てみましょうcat /proc/sysvipc/msg

$ ipcs -q

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages    
0x33ec1686 65536      user       644        0            0           

キューをいくつかのメッセージでいっぱいにします。

$ cat <<EOF >msg_send.c
#include <string.h>
#include <sys/msg.h> 

int main() {
  int msqid = 65536;
  struct message {
    long type;
    char text[20];
  } msg;

  msg.type = 1;
  strcpy(msg.text, "This is message 1");
  msgsnd(msqid, (void *) &msg, sizeof(msg.text), IPC_NOWAIT);
  strcpy(msg.text, "This is message 2");
  msgsnd(msqid, (void *) &msg, sizeof(msg.text), IPC_NOWAIT);

  return 0;
}
EOF

同様に、通常、コードにmsqidをハードコードしません。

$ gcc -o msg_send msg_send.c
$ ./msg_send
$ ipcs -q

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages    
0x33ec1686 65536      user       644        40           2        

相手は次のメッセージを受け取ります。

$ cat <<EOF >msg_recv.c
#include <stdio.h>
#include <sys/msg.h>

int main() {
  int msqid = 65536;
  struct message {
    long type;
    char text[20];
  } msg;
  long msgtyp = 0;

  msgrcv(msqid, (void *) &msg, sizeof(msg.text), msgtyp, MSG_NOERROR | IPC_NOWAIT);
  printf("%s \n", msg.text);

  return 0;
}
EOF

みましょう:

$ gcc -o msg_recv msg_recv.c
$ ./msg_recv
This is message 1
$ ./msg_recv
This is message 2
$ ipcs -q

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages    
0x33ec1686 65536      user       644        0            0           

2回の受信後、キューは再び空になります。

-Q次に、key()またはmsqid()を指定して-q削除します。

$ ipcrm -q 65536

関連情報