ฉันต้องการทราบว่า Message Queues ถูกนำไปใช้ในเคอร์เนล Linux อย่างไร
ฉันต้องการทราบว่า Message Queues ถูกนำไปใช้ในเคอร์เนล Linux อย่างไร
คำตอบ:
เคอร์เนล Linux (2.6) ใช้คิวข้อความสองคิว:
(แทนที่จะเป็น 'รายการข้อความ' เนื่องจากการนำไปใช้งานทำได้โดยการใช้รายการที่เชื่อมโยงโดยไม่ปฏิบัติตามหลักการ FIFO อย่างเคร่งครัด)
ข้อความ System V IPC
คิวข้อความจาก System V
กระบวนการสามารถเรียกใช้msgsnd()
เพื่อส่งข้อความ เขาต้องผ่านตัวระบุ IPC ของคิวข้อความที่ได้รับขนาดของข้อความและโครงสร้างข้อความรวมถึงประเภทข้อความและข้อความ
ในด้านอื่น ๆ ที่จะเรียกกระบวนการmsgrcv()
ที่จะได้รับข้อความผ่านตัวระบุ IPC ของคิวข้อความที่ข้อความควรจะได้รับการจัดเก็บขนาดและค่าที
tระบุข้อความที่ส่งคืนจากคิวค่าบวกหมายถึงข้อความแรกที่มีชนิดเท่ากับtถูกส่งคืนค่าลบส่งคืนข้อความสุดท้ายเท่ากับ type tและศูนย์ส่งคืนข้อความแรกของคิว
ฟังก์ชั่นเหล่านั้นถูกกำหนดไว้ในinclude / linux / msg.hและนำมาใช้ในipc / msg.c
มีข้อ จำกัด ตามขนาดของข้อความ (สูงสุด), จำนวนข้อความทั้งหมด (mni) และขนาดรวมของข้อความทั้งหมดในคิว (mnb):
$ sysctl kernel.msg{max,mni,mnb}
kernel.msgmax = 8192
kernel.msgmni = 1655
kernel.msgmnb = 16384
การส่งออกดังกล่าวข้างต้นมีที่มาจากอูบุนตู 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