Câu trả lời:
Nhân Linux (2.6) thực hiện hai hàng đợi tin nhắn:
(thay vì 'danh sách tin nhắn', vì việc triển khai được thực hiện bằng cách sử dụng danh sách được liên kết không tuân thủ nghiêm ngặt nguyên tắc FIFO)
Tin nhắn hệ thống V IPC
Hàng đợi tin nhắn từ Hệ thống V.
Một quá trình có thể gọi msgsnd()
để gửi một tin nhắn. Anh ta cần phải vượt qua định danh IPC của hàng đợi tin nhắn nhận, kích thước của tin nhắn và cấu trúc tin nhắn, bao gồm loại tin nhắn và văn bản.
Mặt khác, một quá trình gọi msgrcv()
để nhận một tin nhắn, chuyển qua định danh IPC của hàng đợi tin nhắn, nơi tin nhắn sẽ được lưu trữ, kích thước và giá trị t .
t chỉ định tin nhắn được trả về từ hàng đợi, giá trị dương nghĩa là tin nhắn đầu tiên có loại bằng t được trả về, giá trị âm trả về tin nhắn cuối cùng bằng loại t và 0 trả về tin nhắn đầu tiên của hàng đợi.
Các chức năng này được xác định trong tệp bao gồm / linux / dir.h và được triển khai trong ipc / dir.c
Có các giới hạn về kích thước của tin nhắn (tối đa), tổng số tin nhắn (mni) và tổng kích thước của tất cả các tin nhắn trong hàng đợi (mnb):
$ sysctl kernel.msg{max,mni,mnb}
kernel.msgmax = 8192
kernel.msgmni = 1655
kernel.msgmnb = 16384
Đầu ra ở trên là từ hệ thống Ubuntu 10.10, mặc định được xác định trong tệp tin .
Công cụ xếp hàng tin nhắn System V cực kỳ cũ được giải thích ở đây .
Hàng đợi tin nhắn POSIX
Tiêu chuẩn POSIX xác định cơ chế hàng đợi tin nhắn dựa trên hàng đợi tin nhắn của System V IPC, mở rộng nó bằng một số chức năng:
Xem ipc / mqueue.c
Thí dụ
util-linux
cung cấp một số chương trình để phân tích và sửa đổi hàng đợi tin nhắn và đặc tả POSIX cung cấp một số ví dụ C:
Tạo một hàng đợi tin nhắn với ipcmk
; nói chung bạn sẽ làm điều này bằng cách gọi các hàm C như ftok()
và msgget()
:
$ ipcmk -Q
Hãy xem những gì đã xảy ra bằng cách sử dụng ipcs
hoặc với cat /proc/sysvipc/msg
:
$ ipcs -q
------ Message Queues --------
key msqid owner perms used-bytes messages
0x33ec1686 65536 user 644 0 0
Bây giờ điền vào hàng đợi với một số tin nhắn:
$ 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
Một lần nữa, bạn thường không mã hóa msqid trong mã.
$ 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
Và phía bên kia, sẽ nhận được tin nhắn:
$ 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
Xem những gì xảy ra:
$ 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
Sau khi nhận được hai, hàng đợi lại trống.
Xóa nó sau đó bằng cách chỉ định khóa ( -Q
) hoặc msqid ( -q
):
$ ipcrm -q 65536