next up previous contents
Next: Shared Memory Up: System V IPC Previous: Semaphoren   Contents

Message queues

Message queues, erlauben Prozessen Nachrichten zu schreiben, die von anderen Prozessen gelesen werden können. Diese Nachrichten sind einfach eine Folge von Bytes, können jedoch eine bestimmte Typkennzeichnung haben. Prozesse können den Empfang von Nachrichten auf einen bestimmten Typ einschränken. Die Grundlage der Implementierung unter Linux ist die Struktur msg_queue [ipc/msg.c]:

struct msg_queue { 
  struct kern_ipc_perm q_perm; 
  time_t q_stime;          /* last msgsnd time */ 
  time_t q_rtime;          /* last msgrcv time */  
  time_t q_ctime;          /* last change time */ 
  unsigned long q_cbytes;  /* current number of bytes on queue */ 
  unsigned long q_qnum;    /* number of messages in queue */ 
  unsigned long q_qbytes;  /* max number of bytes on queue */ 
  pid_t q_lspid;           /* pid of last msgsnd */ 
  pid_t q_lrpid;           /* last receive pid */ 
 
  struct list_head q_messages; 
  struct list_head q_receivers; 
  struct list_head q_senders; 
};
Es ist wieder die Struktur kern_ipc_perm enthalten, welche die Zugriffsrechte regelt (s.o.). Neben weiteren Verwaltungsinformationen, werden drei Listen angelegt. q_messages ist die Liste der ungelesenen Nachrichten. Sie besteht aus Elementen der Struktur msg_msg.

struct msg_msg { 
  struct list_head m_list; 
  long m_type; 
  int m_ts;     /* message text size */ 
  struct msg_msgseg* next; 
  /* the actual message follows immediately */ 
};
m_type ist der Typ der Nachricht. m_ts die Grösse. next weist auf den nächsten Eintrag in der message queue.

struct msg_msgseg { 
  struct msg_msgseg* next; 
  /* the next part of the message follows immediately */ 
};
Die Daten der Nachricht selber, folgen immer direkt im Anschluss an das Feld next.

Die Liste q_receivers der msg_queue ist eine Liste der Prozesse die auf Daten in der message queue warten. Sie besteht aus Feldern der Struktur msg_receiver:

struct msg_receiver { 
  struct list_head r_list; 
  struct task_struct* r_tsk; 
  int r_mode; 
  long r_msgtype; 
  long r_maxsize; 
  struct msg_msg* volatile r_msg; 
};
Der Prozess selber wird in der task_struct* r_tsk gespeichert. r_msgtype ist der Typ der Nachricht auf die der Prozess wartet, wobei der Wert Null bedeutet, dass der Prozess Nachrichten jeden Typs annimmt. r_maxsize ist die maximale Grösse der Nachricht in Bytes.

Die Liste q_senders der msg_queue ist eine Liste der Prozesse die darauf warten Daten in die message queue schreiben zu können, z.B. weil die message queue voll ist. Sie besteht aus Feldern der Struktur msg_sender:

struct msg_sender { 
  struct list_head list; 
  struct task_struct* tsk; 
};
und diese besteht nur aus task_struct's für die jeweiligen Prozesse.

Prozesse können mit der Funktion

int msgget ( key_t key, int msgflg )
eine message queue erzeugen. Ist key noch nicht benutzt oder hat den besonderen Wert IPC_PRIVATE, so wird eine neue messsage queue angelegt und eine msqid zurückgegeben, über die man Daten in die Queue schreiben oder von ihr lesen kann. Referenziert key eine bereits existierendes message queue, so wird nur die damit assoziierte msqid zurückgegeben.

Daten von einer message queue lesen, kann ein Prozess mit der Funktion

ssize_t msgrcv ( int msqid, struct msgbuf *msgp, size_t msgsz, long msgtyp, int msgflg )
msgid ist der von msgget() zurückgegebene Wert. msgp ist die Adresse auf eine Struktur vom Typ msgbuf in der die Daten aus der message queue kopiert werden. msgsz ist die maximale Grösse der Nachricht. Ist die Nachricht grösser wird entweder eine Fehlermeldung zurückgegeben oder wenn das Flag MSG_NOERROR in msgflg gesetzt ist, die Nachricht abgeschnitten und der Rest geht verloren. msgtyp ist der Typ der zu empfangenden Nachricht. Wurde eine Nachricht von einem Prozess empfangen, wird sie aus der q_messages Liste entfernt.

Daten in eine message queue senden , kann ein Prozess mit der Funktion

int msgsnd ( int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg )
msgid ist dabei wieder die ID der message_queue. msgp ein Zeiger auf eine Struktur msgbuf welche die Daten der Nachricht von der Grösse msgsz enthält. Über ein Flag IPC_NOWAIT kann der Prozess in msgflg signalisieren, dass er nicht blockieren möchte, wenn es im Moment nicht möglich ist die Nachricht zu senden (z.B. weil die message queue voll ist). Statt dessen kehrt msgsnd() dann gleich mit einer Fehlermeldung zurück.

msgbuf hat folgende Struktur:

struct msgbuf { 
  long mtype;     /* type of message */ 
  char mtext[1];  /* message text */ 
};
Message queues erlauben zwar den Zugriff von mehreren Prozessen, die Daten können jedoch nur in 1:1 Beziehung ausgetauscht werden.


next up previous contents
Next: Shared Memory Up: System V IPC Previous: Semaphoren   Contents
2002-02-17