Processes do not share an address space by default. Inter-process communication (IPC) supplies an explicit data path or synchronization primitive across that boundary. The right mechanism follows from data shape, addressing, lifetime, throughput, and failure handling—not from a universal speed ranking.

MechanismData and addressingLifetime / failure boundaryGood fit
Anonymous pipeUnidirectional byte stream between related processesEnds when endpoints close; writers fail after readers disappearParent/child streaming and redirected command output
Named pipeNamed byte or message channel between local or remote processesName enables unrelated processes to rendezvous; capacity creates backpressureLocal services and simple request/response protocols
Local socketStream or datagram between local endpointsConnection shutdown is explicit; platform addressing and credential support varyRequest/response protocols and independently restarted services
Message queueDiscrete prioritized messages through a named kernel queueQueue can outlive processes until removed; finite capacity creates backpressure or failureSmall messages that must preserve boundaries
Shared memoryThe same mapped pages in multiple processesFast data path, but readers can observe torn or stale state without synchronizationLarge buffers and high-throughput local exchange
SignalSmall asynchronous notification, usually carrying no payloadDelivery and coalescing rules limit protocol complexityCancellation, child status, reload notification
Semaphore / event primitiveSynchronization state rather than application dataOwner failure can strand poorly designed protocolsCoordinating access to shared memory or resources

Shared memory avoids copying application payloads through a pipe or socket, but it does not make a protocol safe. The processes still need ownership rules, memory ordering, bounds checks, and a recovery strategy if one participant dies while updating shared state. A socket often wins when message framing, access control, and independent restart matter more than the last copy.

Local request/response in .NET

NamedPipeServerStream provides a local IPC endpoint without opening a network port:

using System.IO.Pipes;
 
await using var server = new NamedPipeServerStream(
    "devbook",
    PipeDirection.InOut,
    maxNumberOfServerInstances: 16,
    PipeTransmissionMode.Byte,
    PipeOptions.Asynchronous);
 
await server.WaitForConnectionAsync();
byte[] buffer = new byte[4096];
int received = await server.ReadAsync(buffer);
await server.WriteAsync(buffer.AsMemory(0, received));

Production code must define framing for multiple messages, restrict endpoint access, handle partial reads and receiver-side message fragmentation, and set cancellation or timeouts. Named-pipe behavior differs by platform, so protocol tests must run on every deployment target.

References