std.ipc_sysv — SysV IPC (Shared Memory, Semaphore, Message Queues)

import std.ipc_sysv;

SysV IPC ist der klassische POSIX-Mechanismus für Inter-Prozess-Kommunikation: gemeinsamer Speicher (Shared Memory), Semaphore und Message Queues. Alle Objekte werden über Integer-Keys identifiziert, nicht über Pfade.

std.ns · std.os · Handles und Dateideskriptoren


Allgemeine Konstanten

Konstante Wert Bedeutung
IPC_PRIVATE 0 Privater Key — nur für den erzeugenden Prozess und seine Kinder sichtbar
IPC_CREAT 512 Anlegen falls nicht vorhanden
IPC_EXCL 1024 Fehler wenn bereits vorhanden (nur mit IPC_CREAT sinnvoll)
IPC_RMID 0 Objekt löschen

Shared Memory

Konstanten

Konstante Wert Bedeutung
SHM_RDONLY 4096 Segment nur lesend mappen

Funktionen

Funktion Signatur Beschreibung
ShmCreate (key: int64, size: int64, flags: int64): int64 Erzeugt oder öffnet ein Shared-Memory-Segment; gibt shmId zurück
ShmAttach (shmId: int64, addr: int64, flags: int64): int64 Mappt Segment in den Prozess-Adressraum; addr=0 → Kernel wählt
ShmDetach (addr: int64): int64 Entfernt Mapping aus Adressraum (kein Löschen)
ShmDelete (shmId: int64): int64 Löscht das Segment wenn kein Prozess mehr gemappt ist

Verwendung

import std.ipc_sysv;
import std.io;

fn main(): int64 {
    // Segment anlegen: IPC_PRIVATE + IPC_CREAT + Rechte 0o666
    var shmId: int64 := ShmCreate(IPC_PRIVATE, 4096, IPC_CREAT | 438);
    if (shmId < 0) { return shmId; }

    // In Adressraum einblenden
    var mem: int64 := ShmAttach(shmId, 0, 0);
    if (mem < 0) { ShmDelete(shmId); return mem; }

    // Daten schreiben/lesen
    poke64(mem, 42);
    var v: int64 := peek64(mem);

    // Aufräumen
    ShmDetach(mem);
    ShmDelete(shmId);
    return 0;
}


Semaphore

Konstanten

Konstante Wert Bedeutung
SEMBUF_SIZE 8 Größe der sembuf-Struktur in Bytes
SEM_UNDO 4096 Undo-Operation bei Prozessende
IPC_NOWAIT 2048 Nicht blockieren
SEM_GETVAL 12 Wert einer Semaphore lesen
SEM_SETVAL 16 Wert einer Semaphore setzen

Funktionen

Funktion Signatur Beschreibung
SemCreate (key: int64, nsems: int64, flags: int64): int64 Erzeugt/öffnet Semaphore-Gruppe mit nsems Semaphoren
SemSetVal (semId: int64, semNum: int64, val: int64): int64 Setzt Wert von Semaphore Nr. semNum
SemGetVal (semId: int64, semNum: int64): int64 Liest Wert von Semaphore Nr. semNum
SemWait (semId: int64, semNum: int64): int64 P-Operation: dekrementiert um 1, blockiert wenn 0
SemPost (semId: int64, semNum: int64): int64 V-Operation: inkrementiert um 1
SemDelete (semId: int64): int64 Löscht die Semaphore-Gruppe

Verwendung

import std.ipc_sysv;

fn main(): int64 {
    // Mutex-Semaphore anlegen (1 Semaphore, Initialwert 1)
    var semId: int64 := SemCreate(IPC_PRIVATE, 1, IPC_CREAT | 438);
    if (semId < 0) { return semId; }
    SemSetVal(semId, 0, 1);  // Semaphore 0 auf Wert 1 setzen

    // Kritischen Abschnitt schützen
    SemWait(semId, 0);   // Lock
    // ... kritischer Abschnitt ...
    SemPost(semId, 0);   // Unlock

    SemDelete(semId);
    return 0;
}


Message Queues

Konstanten

Konstante Wert Bedeutung
MSG_HDR_SIZE 8 Größe des mtype-Headers im msgbuf
MSG_NOERROR 4096 Nachricht abschneiden statt -E2BIG

Funktionen

Funktion Signatur Beschreibung
MsgQueueCreate (key: int64, flags: int64): int64 Erzeugt/öffnet Message-Queue; gibt mqId zurück
MsgSend (mqId: int64, buf: int64, size: int64, flags: int64): int64 Sendet Nachricht; buf: erste 8 Bytes = mtype (> 0), dann Nutzdaten
MsgRecv (mqId: int64, buf: int64, size: int64, msgType: int64, flags: int64): int64 Empfängt Nachricht; gibt Nutzdaten-Bytes zurück
MsgQueueDelete (mqId: int64): int64 Löscht die Queue

Verwendung

import std.ipc_sysv;
import std.alloc;

fn main(): int64 {
    var mqId: int64 := MsgQueueCreate(IPC_PRIVATE, IPC_CREAT | 438);
    if (mqId < 0) { return mqId; }

    // Senden: 8 Bytes mtype-Header + 16 Bytes Nutzdaten
    var sendBuf: int64 := alloc(24);
    poke64(sendBuf, 1);          // mtype = 1 (muss > 0)
    poke64(sendBuf + 8, 0x1234); // Nutzdaten
    poke64(sendBuf + 16, 0x5678);
    MsgSend(mqId, sendBuf, 16, 0);

    // Empfangen
    var recvBuf: int64 := alloc(24);
    var n: int64 := MsgRecv(mqId, recvBuf, 16, 1, 0);
    // n = 16, recvBuf+8 = Nutzdaten

    free(sendBuf, 24);
    free(recvBuf, 24);
    MsgQueueDelete(mqId);
    return 0;
}


Hinweise

  • IPC_PRIVATE: Erstellt ein Objekt das nicht über einen Integer-Key von anderen Prozessen gefunden werden kann — geeignet für Eltern-Kind-Kommunikation (vor dem fork()).
  • Schlüssel-Konflikte: Bei festem Key und IPC_CREAT ohne IPC_EXCL wird ein bestehendes Objekt geöffnet — kann zu unerwarteten Verbindungen mit anderen Prozessen führen.
  • msgbuf-Layout: Die ersten 8 Bytes des Puffers sind immer der mtype (int64, muss > 0). Die size-Parameter in MsgSend/MsgRecv zählen ohne diesen Header.
  • Persistenz: SysV-IPC-Objekte überleben den Prozess — explizites ShmDelete/SemDelete/MsgQueueDelete ist nötig. Vergessene Objekte sichtbar mit: ipcs.
  • Alternative: Für moderne Anwendungen bevorzugt mmap + Datei oder POSIX-Semaphore (sem_open).

Letzte Aktualisierung: 2026-06-06