Antworten:
Der Linux-Kernel (2.6) implementiert zwei Nachrichtenwarteschlangen:
(eher 'Nachrichtenlisten', da die Implementierung über eine verknüpfte Liste erfolgt, die nicht strikt dem FIFO-Prinzip folgt.)
System V IPC-Nachrichten
Die Nachrichtenwarteschlange von System V.
Ein Prozess kann msgsnd()
zum Senden einer Nachricht aufgerufen werden. Er muss die IPC-Kennung der empfangenden Nachrichtenwarteschlange, die Größe der Nachricht und eine Nachrichtenstruktur einschließlich Nachrichtentyp und Text übergeben.
Auf der anderen Seite ruft ein Prozess auf msgrcv()
, um eine Nachricht zu empfangen, und übergibt die IPC-Kennung der Nachrichtenwarteschlange, in der die Nachricht gespeichert werden soll, die Größe und einen Wert t .
t gibt die von der Warteschlange zurückgegebene Nachricht an. Ein positiver Wert bedeutet, dass die erste Nachricht mit dem Typ t zurückgegeben wird. Ein negativer Wert gibt die letzte Nachricht mit dem Typ t zurück und null gibt die erste Nachricht der Warteschlange zurück.
Diese Funktionen sind in include / linux / msg.h definiert und in ipc / msg.c implementiert
Es gibt Einschränkungen hinsichtlich der Größe einer Nachricht (max), der Gesamtzahl der Nachrichten (mni) und der Gesamtgröße aller Nachrichten in der Warteschlange (mnb):
$ sysctl kernel.msg{max,mni,mnb}
kernel.msgmax = 8192
kernel.msgmni = 1655
kernel.msgmnb = 16384
Die Ausgabe oben stammt von einem Ubuntu 10.10-System, die Standardeinstellungen sind in msg.h definiert .
Weitere Informationen zu unglaublich alten System V-Nachrichtenwarteschlangen finden Sie hier .
POSIX-Nachrichtenwarteschlange
Der POSIX-Standard definiert einen Nachrichtenwarteschlangenmechanismus, der auf der Nachrichtenwarteschlange von System V IPC basiert und diese um einige Funktionen erweitert:
Siehe ipc / mqueue.c
Beispiel
util-linux
stellt einige Programme zum Analysieren und Ändern von Nachrichtenwarteschlangen bereit, und die POSIX-Spezifikation enthält einige C-Beispiele:
Erstellen Sie eine Nachrichtenwarteschlange mit ipcmk
; Im Allgemeinen würden Sie dies tun, indem Sie C-Funktionen wie ftok()
und aufrufen msgget()
:
$ ipcmk -Q
Mal sehen, was passiert ist mit ipcs
oder mit cat /proc/sysvipc/msg
:
$ ipcs -q
------ Message Queues --------
key msqid owner perms used-bytes messages
0x33ec1686 65536 user 644 0 0
Füllen Sie nun die Warteschlange mit einigen Nachrichten:
$ 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
Auch hier codieren Sie die msqid im Allgemeinen nicht fest im Code.
$ 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
Und die andere Seite, die die Nachrichten erhalten wird:
$ 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
Schau was passiert:
$ 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
Nach zwei Empfängen ist die Warteschlange wieder leer.
Entfernen Sie es anschließend, indem Sie key ( -Q
) oder msqid ( -q
) angeben :
$ ipcrm -q 65536