Skip to content

Shared memory

Category: Communication · Status: stub · Lessons: chapter 02, Shared state

One line: Tasks read and write the same memory directly and coordinate with locks or atomics — the fastest way to share data, and the easiest to get wrong.

How it connects

flowchart LR
  n_data_race["Data race"]
  n_message_passing["Message passing"]
  n_shared_memory["Shared memory"]
  n_message_passing ---|or| n_shared_memory
  n_shared_memory -->|can cause| n_data_race
  classDef center stroke-width:3px
  class n_shared_memory center
  classDef outside stroke-dasharray: 4 3
  class n_data_race,n_message_passing outside

In each language

Rust an Arc is a thread-safe reference-counting pointer that does not allow mutation by itself; put a Mutex or an atomic inside to mutate
Go sync.Mutex and sync/atomic exist, but the sync docs say most of them are for low-level library routines and higher-level synchronization is better done via channels
C threads guard shared data with a mutex, pthread_mutex_lock
C++ std::mutex and std::atomic
Java synchronized, ReentrantLock, and atomics such as AtomicInteger
Python threads share objects and guard them with threading.Lock; processes can share a block of memory through multiprocessing.shared_memory (3.8)
C# the lock statement
JavaScript workers can share a SharedArrayBuffer, coordinated with Atomics
Kotlin shared mutable state ↗ needs synchronizing as soon as coroutines run on a multi-threaded dispatcher such as Dispatchers.Default
Erlang and Elixir an ETS table ↗ created public can be read and written by any process
Haskell an MVar, a synchronising variable, or STM ↗ transactions
The operating system POSIX shared memory ↗: shm_open creates an object that each process maps into its address space with mmap

Where to read more