Linux 커널에서 메시지 큐는 어떻게 구현됩니까? Linux 커널에서 Message Queue가 어떻게 구현되는지

Linux 커널에서 Message Queue가 어떻게 구현되는지 알고 싶습니다.



답변

리눅스 커널 (2.6)은 두 개의 메시지 큐를
구현한다.

System V IPC 메시지

시스템 V의 메시지 큐

프로세스는 msgsnd()메시지를 보내도록 호출 할 수 있습니다 . 수신 메시지 큐의 IPC 식별자, 메시지 크기 및 메시지 유형 및 텍스트를 포함한 메시지 구조를 전달해야합니다.

다른 한편으로, 프로세스는 msgrcv()메시지를 수신하기 위해 호출 하고 메시지 큐의 IPC 식별자, 메시지를 저장해야하는 위치, 크기 및 값 t를 전달 합니다.

t 는 큐에서 리턴 된 메시지를 지정하고, 양수 값은 t 와 동일한 유형의 첫 번째 메시지 가 리턴 됨을 의미하고 , 음수 값은 유형 t 와 같은 마지막 메시지를 리턴하고 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 시스템에서 가져온 것이며 기본값은 msg.h에 정의되어 있습니다.

좀 더 오래된 System V 메시지 대기열 내용은 여기에 설명되어 있습니다 .

POSIX 메시지 큐

POSIX 표준은 System V IPC의 메시지 큐를 기반으로 메시지 큐 메커니즘을 정의하여 일부 기능으로 확장합니다.

  • 응용 프로그램에 대한 간단한 파일 기반 인터페이스
  • 메시지 우선 순위 지원
  • 비동기 알림 지원
  • 작업 차단을위한 시간 초과

ipc / mqueue.c 참조

util-linux 메시지 큐를 분석하고 수정하기위한 일부 프로그램을 제공하고 POSIX 스펙은 몇 가지 C 예제를 제공합니다.

ipcmk; 로 메시지 대기열을 만듭니다 . 일반적으로는 같은 C 함수를 호출하여이 작업을 수행 할 것입니다 ftok()msgget():

$ ipcmk -Q

사용하여 무슨 일이 있었는지 볼 수 있습니다 ipcs또는 함께 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

두 개의 수신 후 큐가 다시 비워집니다.

키 ( -Q) 또는 msqid ( -q) 를 지정하여 나중에 제거하십시오 .

$ ipcrm -q 65536