Làm thế nào là một hàng đợi tin nhắn được thực hiện trong nhân Linux?


29

Tôi muốn biết cách xếp hàng Tin nhắn được triển khai trong Hạt nhân Linux.


IPC_NOWAIT chúng tôi chỉ sử dụng nó trong công cụ thu hồi
Anwaar Qa

Câu trả lời:


41

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:

  • Giao diện dựa trên tệp đơn giản cho ứng dụng
  • Hỗ trợ ưu tiên tin nhắn
  • Hỗ trợ thông báo không đồng bộ
  • Thời gian chờ cho các hoạt động chặn

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()msgget():

$ ipcmk -Q

Hãy xem những gì đã xảy ra bằng cách sử dụng ipcshoặ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

Vì vậy, tin nhắn (loại và văn bản) có được sao chép / sao chép và sau đó bản sao đó được đưa vào hàng đợi tin nhắn của hệ thống không?
trusktr

rất độc đáo đặt. Cảm ơn bạn cho lời giải thích tuyệt vời này.
Người dùng9102d82
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.