Lassen Sie uns darüber sprechen, wie Nachrichtenwarteschlangen für die Kommunikation zwischen Prozessen verwendet werden. Nachrichtenwarteschlangen haben viele Ähnlichkeiten mit benannten Pipes. Weitere Informationen zu benannten Pipes finden Sie in meinem anderen Artikel: Linux-Interprozesskommunikation – Verwendung benannter Pipes
1. Was ist eine Nachrichtenwarteschlange
Nachrichtenwarteschlangen bieten eine Möglichkeit, einen Datenblock von einem Prozess an einen anderen zu senden. Es wird davon ausgegangen, dass jeder Datenblock einen Typ enthält, und der Empfangsprozess kann unabhängig Datenstrukturen empfangen, die unterschiedliche Typen enthalten. Wir können die Synchronisierungs- und Blockierungsprobleme von Named Pipes vermeiden, indem wir Nachrichten senden. Aber Nachrichtenwarteschlangen haben, wie Named Pipes, eine maximale Längenbeschränkung für jeden Datenblock.
Linux verwendet die Makros MSGMAX und MSGMNB, um die maximale Länge einer Nachricht und die maximale Länge einer Warteschlange zu begrenzen.
2. Verwenden von Nachrichtenwarteschlangen unter Linux
Linux bietet eine Reihe von Nachrichtenwarteschlangen-Funktionsschnittstellen, mit denen wir es einfach zur Implementierung der Kommunikation zwischen Prozessen verwenden können. Seine Verwendung ähnelt den anderen beiden PIC-Mechanismen von System V, Semaphoren und Shared Memory.
1. msgget-Funktion
Diese Funktion wird zum Erstellen und Zugreifen auf eine Nachrichtenwarteschlange verwendet. Sein Prototyp ist:
int msgget(key_t, key, int msgflg);
mit anderen IPC-Mechanismen Ist das Gleiche, muss das Programm einen Schlüssel bereitstellen, um eine bestimmte Nachrichtenwarteschlange zu benennen. msgflg ist ein Berechtigungsflag, das die Zugriffsberechtigung der Nachrichtenwarteschlange angibt, die mit der Zugriffsberechtigung der Datei identisch ist. msgflg kann mit IPC_CREAT verknüpft werden, was bedeutet, dass eine Nachrichtenwarteschlange erstellt wird, wenn die durch den Schlüssel benannte Nachrichtenwarteschlange nicht existiert. Wenn die durch den Schlüssel benannte Nachrichtenwarteschlange vorhanden ist, wird das IPC_CREAT-Flag ignoriert und nur eine Kennung zurückgegeben.
Es gibt eine Kennung (Ganzzahl ungleich Null) der durch den Schlüssel benannten Nachrichtenwarteschlange zurück und gibt -1 bei einem Fehler zurück
2 . msgsnd-Funktion
Diese Funktion wird verwendet, um Nachrichten zur Nachrichtenwarteschlange hinzuzufügen. Sein Prototyp ist:
int msgsend(int msgid, const void *msg_ptr, size_t msg_sz, int msgflg);
msgid ist die Nachrichtenwarteschlangen-ID, die von der msgget-Funktion zurückgegeben wird.
msg_ptr ist ein Zeiger auf die zu sendende Nachricht, aber die Datenstruktur der Nachricht stellt bestimmte Anforderungen. Die Nachrichtenstruktur, auf die der Zeiger msg_ptr zeigt, muss mit einem langen ganzzahligen Mitglied beginnen Variable Struktur, die Empfangsfunktion verwendet dieses Mitglied, um den Nachrichtentyp zu bestimmen. Die Nachrichtenstruktur sollte also wie folgt definiert sein:
struct my_message{
long int message_type; > /* Die Daten, die Sie übertragen möchten*/
msg_sz ist die Länge der Nachricht, auf die msg_ptr zeigt. Beachten Sie, dass es sich um die Länge der Nachricht handelt, nicht um die Länge der gesamten Struktur. Das heißt, msg_sz enthält nicht die Länge der Mitgliedsvariablen vom Typ „Long Integer“.
msgflg wird verwendet, um zu steuern, was passiert, wenn die aktuelle Nachrichtenwarteschlange voll ist oder die Warteschlangennachricht das systemweite Limit erreicht.
Wenn der Aufruf erfolgreich ist, wird eine Kopie der Nachrichtendaten in die Nachrichtenwarteschlange gestellt und 0 zurückgegeben. Wenn er fehlschlägt, wird -1 zurückgegeben
3. msgrcv-Funktion
Diese Funktion wird verwendet, um Nachrichten aus einer Nachrichtenwarteschlange abzurufen. Ihr Prototyp ist
[cpp]
Einfache Kopie anzeigen
Drucken?
msgid, msg_ptr, msg_st funktionieren auch mit msgsnd Funktion.
msgtype kann eine einfache Empfangspriorität implementieren. Wenn msgtype 0 ist, wird die erste Nachricht in der Warteschlange abgerufen. Wenn sein Wert größer als Null ist, wird die erste Nachricht mit demselben Nachrichtentyp erhalten. Wenn er kleiner als Null ist, wird die erste Nachricht abgerufen, deren Typ kleiner oder gleich dem absoluten Wert von msgtype ist.
msgflg wird verwendet, um zu steuern, was passiert, wenn keine Nachricht des entsprechenden Typs in der Warteschlange zum Empfangen vorhanden ist.
Bei erfolgreichem Aufruf gibt diese Funktion die Anzahl der im Empfangspuffer platzierten Bytes zurück, die Nachricht wird in den vom Benutzer zugewiesenen Puffer kopiert, auf den msg_ptr zeigt, und dann aus der Nachricht gelöscht entsprechende Nachricht in die Warteschlange stellen. Gibt bei einem Fehler -1 zurück.
4. msgctl-Funktion
Diese Funktion ähnelt der shmctl-Funktion von Shared Memory Prototyp ist:
- int msgctl(
int msgid, int command, struct msgid_ds *buf);
Befehl ist die auszuführende Aktion, er kann 3 Werte annehmen,
IPC_STAT: Setzt die Daten in der msgid_ds-Struktur auf den aktuell zugeordneten Wert der Nachrichtenwarteschlange Das heißt, es wird der aktuell zugeordnete Wert der Nachrichtenwarteschlange verwendet. Der zugeordnete Wert überschreibt den Wert von msgid_ds.
IPC_SET: Wenn der Prozess über ausreichende Berechtigungen verfügt, setzen Sie den aktuellen zugehörigen Wert der Nachrichtenwarteschlange auf den in der msgid_ds-Struktur angegebenen Wert
IPC_RMID: Löschen Sie die Nachrichtenwarteschlange
buf ist ein Zeiger auf die msgid_ds-Struktur, die auf die Struktur des Nachrichtenwarteschlangenmodus und der Zugriffsrechte verweist. Die msgid_ds-Struktur enthält mindestens die folgenden Mitglieder:
- struct msgid_ds
{ uid_t shm_perm.uid ; uid_t shm_perm.gid; mode_t shm_perm.mode; };
Gibt 0 bei Erfolg und -1 bei Fehler zurück.
3. Prozesskommunikation
Ohne anzuhalten, werfen wir nach der Einführung der Definition der Nachrichtenwarteschlange und der verwendbaren Schnittstellen einen Blick darauf, wie Prozesse kommunizieren können. Da unabhängige Prozesse kommunizieren können, werden wir hier zwei Programme schreiben, msgreceive und msgsned, um das Empfangen und Senden von Informationen darzustellen. Unter normalen Umständen erlauben wir beiden Programmen, Nachrichten zu erstellen, aber nur der Empfänger löscht die letzte Nachricht, nachdem er sie empfangen hat.
Die Programmquelldatei zum Empfangen von Informationen ist msgreceive.c und der Quellcode ist:
[cpp]
Einfache Kopie anzeigen
Drucken?
发送信息的程序的源文件msgsend.c的源代码为:
#include
#include
#include
#include
#include
#include
#define MAX_TEXT 512
struct msg_st
{
long int msg_type;
char text[MAX_TEXT];
};
int main()
-
{
int running = 1;
struct msg_st data;
char buffer[BUFSIZ];
int msgid = -1;
msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
if(msgid == -1)
{
fprintf(stderr, "msgget failed with error: %dn", errno);
exit(EXIT_FAILURE);
}
while(running)
{
-
printf("Enter some text: ");
fgets(buffer, BUFSIZ, stdin);
data.msg_type = 1;
strcpy(data.text, buffer);
if(msgsnd(msgid, (void *)&data, MAX_TEXT, 0) == -1)
{
fprintf(stderr, "msgsnd failedn");
exit(EXIT_FAILURE);
}
if(strncmp(buffer, "end", 3) == 0)
running = 0;
schlaf(1);
}
exit(EXIT_SUCCESS);
}
运行结果如下:
4. Beispielanalyse – Nachrichtentyp
Hier erklären wir hauptsächlich, was der Nachrichtentyp ist, der in der Hauptfunktion der Datei msgreceive.c definiert ist (annotiert als Anmerkung 1). Sie wird als Wert des empfangenen Informationstypparameters verwendet msgrcv-Funktion, und ihr Wert ist 0 , was angibt, dass die erste verfügbare Nachricht in der Warteschlange abgerufen wird. Schauen wir uns die Anweisung data.msg_type = 1 in der while-Schleife in der Datei msgsend.c an (Hinweis 2). Sie wird verwendet, um den Informationstyp der gesendeten Informationen festzulegen, dh der Typ der gesendeten Informationen ist 1 . So kann das Programm msgceive die vom Programm msgsend gesendeten Informationen empfangen.
Was passiert, wenn Hinweis 1, also die Anweisung in der Hauptfunktion der Datei msgreceive.c, von long int msgtype = 2; , msgreceive kann die vom Programm msgsend gesendeten Informationen nicht empfangen. Denn wenn beim Aufrufen der msgrcv-Funktion msgtype (der vierte Parameter) größer als Null ist, wird nur die erste Nachricht mit demselben Nachrichtentyp abgerufen. Nach der Änderung ist der erhaltene Nachrichtentyp 2 und der von msgsend gesendete Nachrichtentyp 1. Es kann also nicht vom msgreceive-Programm empfangen werden. Kompilieren Sie die Datei msgreceive.c erneut und führen Sie sie erneut aus. Das Ergebnis ist wie folgt:
Wir können sehen Das msgreceive Es werden keine Informationen oder Ausgaben empfangen, und wenn die Eingaben von msgsend enden, wird msgreceive nicht beendet. Über den Befehl jobs können wir sehen, dass er immer noch im Hintergrund ausgeführt wird.
5. Vergleich von Nachrichtenwarteschlangen und benannten Pipes
Nachrichtenwarteschlangen und benannte Pipes weisen viele Ähnlichkeiten auf Die Warteschlange kann aus unabhängigen Prozessen bestehen und alle übertragen Daten durch Senden und Empfangen. In einer benannten Pipe wird „Schreiben“ zum Senden von Daten und „Lesen“ zum Empfangen von Daten verwendet. In einer Nachrichtenwarteschlange wird „msgsnd“ zum Senden von Daten und „msgrcv“ zum Empfangen von Daten verwendet. Und sie haben eine maximale Längenbeschränkung für alle Daten.
Im Vergleich zu Named Pipes bestehen die Vorteile von Nachrichtenwarteschlangen darin, dass 1. Nachrichtenwarteschlangen auch unabhängig von den Sende- und Empfangsprozessen existieren können, wodurch die Notwendigkeit entfällt, das Öffnen und Schließen von Nachrichtenwarteschlangen zu synchronisieren Named Pipes können auftreten. 2. Gleichzeitig können durch das Senden von Nachrichten auch die Synchronisierungs- und Blockierungsprobleme von Named Pipes vermieden werden, und es ist nicht erforderlich, dass der Prozess selbst Synchronisierungsmethoden bereitstellt. 3. Das empfangende Programm kann selektiv Daten über Nachrichtentypen empfangen, anstatt Daten standardmäßig nur zu empfangen, wie bei Named Pipes.
Das obige ist der detaillierte Inhalt vonWas ist eine Nachrichtenwarteschlange? Verwenden der Nachrichtenwarteschlange unter Linux. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!