Come viene implementata una coda di messaggi nel kernel Linux?


29

Vorrei sapere come sono implementate le code dei messaggi nel kernel di Linux.


IPC_NOWAIT lo usiamo solo nel
ricevitore

Risposte:


41

Il kernel Linux (2.6) implementa due code di messaggi:
(piuttosto "elenchi di messaggi", poiché l'implementazione viene eseguita utilizzando un elenco collegato che non segue rigorosamente il principio FIFO)

Messaggi IPC di System V

La coda dei messaggi da System V.

Un processo può invocare msgsnd()per inviare un messaggio. Deve passare l'identificatore IPC della coda dei messaggi di ricezione, la dimensione del messaggio e una struttura del messaggio, inclusi il tipo e il testo del messaggio.

Dall'altro lato, un processo invoca msgrcv()per ricevere un messaggio, passando l'identificatore IPC della coda messaggi, dove il messaggio dovrebbe essere memorizzato, la dimensione e un valore t .

t specifica il messaggio restituito dalla coda, un valore positivo indica che viene restituito il primo messaggio con il suo tipo uguale a t , un valore negativo restituisce l'ultimo messaggio uguale al tipo t e zero restituisce il primo messaggio della coda.

Tali funzioni sono definite in include / linux / msg.h e implementate in ipc / msg.c

Esistono limitazioni sulla dimensione di un messaggio (max), sul numero totale di messaggi (mni) e sulla dimensione totale di tutti i messaggi nella coda (mnb):

$ sysctl kernel.msg{max,mni,mnb}
kernel.msgmax = 8192
kernel.msgmni = 1655
kernel.msgmnb = 16384

L'uscita sopra è da un sistema Ubuntu 10.10, i valori predefiniti sono definiti in msg.h .

Altre cose incredibilmente vecchie sulla coda dei messaggi di System V spiegate qui .

Coda messaggi POSIX

Lo standard POSIX definisce un meccanismo di coda messaggi basato sulla coda messaggi di System V IPC, estendendolo con alcune funzionalità:

  • Semplice interfaccia basata su file per l'applicazione
  • Supporto per le priorità dei messaggi
  • Supporto per la notifica asincrona
  • Timeout per operazioni di blocco

Vedi ipc / mqueue.c

Esempio

util-linux fornisce alcuni programmi per l'analisi e la modifica delle code dei messaggi e la specifica POSIX fornisce alcuni esempi C:

Creare una coda di messaggi con ipcmk; generalmente lo faresti chiamando funzioni C come ftok()e msgget():

$ ipcmk -Q

Vediamo cosa è successo usando ipcso con un cat /proc/sysvipc/msg:

$ ipcs -q

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages    
0x33ec1686 65536      user       644        0            0           

Ora riempi la coda con alcuni messaggi:

$ 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

Ancora una volta, in genere non codificare il codice msqid nel codice.

$ 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        

E l'altro lato, che riceverà i messaggi:

$ 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

Guarda cosa succede:

$ 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           

Dopo due ricevute, la coda è di nuovo vuota.

Rimuoverlo in seguito specificando la chiave ( -Q) o msqid ( -q):

$ ipcrm -q 65536

Quindi il messaggio (tipo e testo) viene clonato / copiato e quindi quella copia viene inserita nella coda dei messaggi del sistema?
trusktr,

molto ben messo. Grazie per questa straordinaria spiegazione.
User9102d82
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.