Concurrency and Sharing Patterns: Rust, C, JavaScript, Python

投稿: 2026年5月18日

This is AI-generated content, published for my own reference.

Concurrency is not just about running multiple things at once. The hard part is deciding how data is shared safely.

Rust, C, JavaScript, and Python approach this problem very differently. Rust uses ownership and type-system guarantees. C relies almost entirely on programmer discipline. JavaScript avoids many issues through a single-threaded event loop. Python uses the GIL, which simplifies threading but limits true parallelism.

This guide compares their common concurrency and sharing patterns side by side.

Rust

Ownership system enforces thread safety at compile time.

Pattern Type Use case
Arc<T> Shared ownership (read-only) Immutable data across tasks
Arc<Mutex<T>> Shared + exclusive access Write access, low contention
Arc<RwLock<T>> Shared + read-heavy access Many readers, few writers
mpsc::channel Message passing Producer-consumer
broadcast::channel Multi-consumer messages Pub/sub
tokio::spawn Async task Non-blocking I/O
std::thread::spawn OS thread CPU-bound work
Send / Sync traits Compiler markers Compiler rejects unsafe sharing

Key insight: Rust won't compile if you share data unsafely. No data races at runtime because they're caught at compile time.

C

No built-in safety. Everything is manual and trusts the programmer.

Pattern Type Use case
pthread_mutex_t Mutex Exclusive access to shared memory
pthread_rwlock_t Read-write lock Many readers, few writers
sem_t Semaphore Limit concurrent access count
pthread_cond_t Condition variable Wait for a signal from another thread
pipe() / socketpair() Message passing Inter-thread or inter-process communication
Shared memory (mmap, shmget) Raw shared memory Inter-process sharing
_Atomic / stdatomic.h Atomic operations Lock-free counters, flags

Key insight: Nothing prevents you from reading/writing shared memory without a lock. Data races are silent bugs — no compiler help, no runtime error, just corruption.

JavaScript (Node.js / Browser)

Single-threaded event loop makes most sharing trivial — but also means no true parallelism in the main thread.

Pattern Type Use case
Closures / shared references Same-thread sharing Default — everything is shared, no locks needed
Promise / async-await Cooperative concurrency I/O-bound tasks, interleaved on one thread
setTimeout / queueMicrotask Deferred execution Scheduling work on the event loop
Worker (Web) / worker_threads (Node) True OS threads CPU-bound parallelism
SharedArrayBuffer + Atomics Shared memory across workers Low-level lock-free sharing between threads
postMessage Message passing Worker communication (data is copied/transferred)

Key insight: The event loop is single-threaded, so normal code never races. But it also can't use multiple cores. Worker threads add parallelism but sharing is explicit and limited (SharedArrayBuffer or message copies).

Python

GIL (Global Interpreter Lock) makes threading deceptively simple but limits parallelism.

Pattern Type Use case
threading.Lock / RLock Mutex Protect shared state between threads
threading.Event / Condition Signaling Wait/notify between threads
queue.Queue Thread-safe message passing Producer-consumer
asyncio / async-await Cooperative concurrency I/O-bound, single-threaded (like JS)
multiprocessing.Process Separate processes True CPU parallelism (bypasses GIL)
multiprocessing.Queue / Pipe IPC message passing Communication between processes
multiprocessing.Value / Array Shared memory (IPC) Shared state across processes

Key insight: The GIL means only one thread runs Python bytecode at a time. threading gives concurrency (interleaving) but not parallelism. For true parallelism you need multiprocessing (separate processes, separate memory) or C extensions that release the GIL.

Summary

Safety Parallelism Sharing model
Rust Compile-time enforced Full (threads + async) Ownership + Arc + locks
C None (programmer's job) Full (pthreads) Raw pointers + manual locks
JavaScript Implicit (single-threaded) Limited (Workers) Event loop + message passing
Python GIL hides races (mostly) Limited by GIL (use multiprocessing) GIL + locks or separate processes

The spectrum runs from C (maximum freedom, zero guardrails) to Rust (maximum freedom, compile-time guardrails) to JS/Python (limited parallelism, so sharing is rarely an issue).