Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Advanced IPC Mechanisms

Overview

Beyond basic IPC (pipes, message queues, shared memory), modern systems use sophisticated IPC mechanisms for high performance, security, and complex communication patterns.

Unix Domain Sockets

Overview

Unix domain sockets are like network sockets but use the filesystem namespace instead of IP addresses. They’re faster than TCP sockets (no network overhead) and support both stream and datagram semantics.

#include <sys/socket.h>
#include <sys/un.h>

// Server
int server_fd = socket(AF_UNIX, SOCK_STREAM, 0);
struct sockaddr_un addr;
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, "/tmp/mysocket");
bind(server_fd, (struct sockaddr*)&addr, sizeof(addr));
listen(server_fd, 5);

// Client
int client_fd = socket(AF_UNIX, SOCK_STREAM, 0);
struct sockaddr_un addr;
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, "/tmp/mysocket");
connect(client_fd, (struct sockaddr*)&addr, sizeof(addr));

Unix Domain Sockets vs TCP

FeatureUnix Domain SocketTCP Socket
SpeedFaster (no network stack)Slower (protocol overhead)
ScopeSame machine onlyNetwork-wide
SecurityFile permissionsFirewall/auth
AddressingFilesystem pathIP:port
Data formatBytes or datagramsBytes

Passing File Descriptors

Unix domain sockets can pass open file descriptors between processes:

// Send fd over socket
struct msghdr msg;
struct cmsghdr *cmsg;
char buf[CMSG_SPACE(sizeof(int))];
msg.msg_control = buf;
msg.msg_controllen = sizeof(buf);
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
*(int*)CMSG_DATA(cmsg) = fd_to_pass;
sendmsg(sock_fd, &msg, 0);

D-Bus

Overview

D-Bus is a message bus system for IPC on Linux. It provides:

  • System bus: For system-level services (hardware, network)
  • Session bus: For user applications
flowchart TD
    subgraph "D-Bus Architecture"
        DBUS[D-Bus Daemon]
        APP1[Application 1] --> DBUS
        APP2[Application 2] --> DBUS
        APP3[Application 3] --> DBUS
        DBUS --> APP1
        DBUS --> APP2
        DBUS --> APP3
    end

D-Bus Communication

MethodDescriptionUse Case
SignalsBroadcast eventsNotifications
Method callsRequest-responseRPC
PropertiesGet/set attributesConfiguration

Memory-Mapped IPC

Shared Memory with mmap

// Create shared memory object
int fd = shm_open("/myshm", O_CREAT | O_RDWR, 0666);
ftruncate(fd, SIZE);

// Map into process memory
void *ptr = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

// Use as regular memory
*(int*)ptr = 42;

// Cleanup
munmap(ptr, SIZE);
close(fd);
shm_unlink("/myshm");

Anonymous mmap (parent-child)

// Parent-child shared memory (fork)
void *ptr = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, 
                 MAP_SHARED | MAP_ANONYMOUS, -1, 0);
*(int*)ptr = 0;

if (fork() == 0) {
    // Child
    *(int*)ptr = 42;
    exit(0);
}
wait(NULL);
printf("%d\n", *(int*)ptr); // 42

POSIX Message Queues

#include <mqueue.h>

// Create/open queue
mqd_t mq = mq_open("/myqueue", O_CREAT | O_WRONLY, 0644, NULL);

// Send message
char *msg = "hello";
mq_send(mq, msg, strlen(msg), 0);

// Receive message
char buf[256];
unsigned int prio;
mq_receive(mq, buf, sizeof(buf), &prio);

// Cleanup
mq_close(mq);
mq_unlink("/myqueue");

Message Queue Features

FeaturePOSIX MQSystem V MQ
Interfacemq_open/mq_sendmsgget/msgsnd
PriorityYes (0-31)No
NotificationSignal/threadNone
Max sizeConfigurableSystem limit

Semaphores

POSIX Semaphores

#include <semaphore.h>

// Named semaphore
sem_t *sem = sem_open("/mysem", O_CREAT, 0644, 1);
sem_wait(sem);    // P operation (decrement)
// Critical section
sem_post(sem);    // V operation (increment)
sem_close(sem);
sem_unlink("/mysem");

// Unnamed semaphore (shared memory)
sem_t sem;
sem_init(&sem, 1, 1);  // pshared=1, value=1
sem_wait(&sem);
sem_post(&sem);
sem_destroy(&sem);

Signals

Advanced Signal Handling

#include <signal.h>

// Signal handler with sigaction (reliable)
struct sigaction sa;
sa.sa_handler = handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;  // Restart interrupted syscalls
sigaction(SIGUSR1, &sa, NULL);

// Signal-safe functions only!
// Async-signal-safe: write(), _exit(), signal-safe list
// NOT safe: printf(), malloc(), mutex operations

void handler(int sig) {
    const char msg[] = "Signal received\n";
    write(STDERR_FILENO, msg, sizeof(msg) - 1);
}

Real-time Signals

// Real-time signals (SIGRTMIN to SIGRTMAX)
// - Queued (multiple pending)
// - Can carry data (sigval)
// - Delivered in order

union sigval value;
value.sival_int = 42;
sigqueue(pid, SIGRTMIN, value);

// Receive with sigwaitinfo
siginfo_t info;
sigwaitinfo(&set, &info);
printf("Signal %d, value %d\n", info.si_signo, info.si_value.sival_int);

Comparison of IPC Mechanisms

MechanismSpeedComplexityPersistenceCross-machine
PipeFastLowNoNo
Unix socketFastMediumNoNo
Shared memoryFastestHighNoNo
Message queueMediumMediumOptionalNo
TCP socketSlowerMediumNoYes
D-BusMediumLowNoNo
SignalFastLowNoNo

Interview Questions

Q1: When to use shared memory vs message passing?

Shared memory: High-throughput, latency-sensitive applications. Requires synchronization (semaphores, mutexes). More complex but fastest IPC.

Message passing: Simpler programming model, built-in synchronization. Better for loosely coupled processes. Lower throughput but easier to use correctly.

Q2: How to pass file descriptors between processes?

Use Unix domain sockets with sendmsg()/recvmsg() and SCM_RIGHTS. The kernel duplicates the fd in the receiving process’s fd table. This is how fork() and exec chains share files.

Q3: What is the Thundering Herd problem?

When multiple processes/threads are waiting on a resource and it becomes available, all wake up but only one can proceed. Solutions:

  • EPOLLEXCLUSIVE (Linux 4.5+)
  • Accept mutex (nginx approach)
  • Wake-one patterns

Q4: System V vs POSIX IPC?

System VPOSIX
Older standardModern standard
msgget/shmget/semgetmq_open/shm_open/sem_open
Key-based namingPath-based naming
Less flexibleMore features (notifications, priorities)