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의 메시지 큐를 기반으로 메시지 큐 메커니즘을 정의하여 일부 기능으로 확장합니다.
- 응용 프로그램에 대한 간단한 파일 기반 인터페이스
- 메시지 우선 순위 지원
- 비동기 알림 지원
- 작업 차단을위한 시간 초과
예
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