Skip to content
Back to skills

Principle Concurrency

ASecurity

Concurrency principles — race conditions, deadlock, livelock, starvation, structured concurrency, cancellation propagation, backpressure, lock-free primitives, atomics, memory models, choosing between mutex vs channel vs actor vs semaphore vs CAS. Auto-load when designing concurrent code, debugging a race condition, fixing a deadlock, propagating cancellation, choosing a synchronization primitive, designing worker pools, or reasoning about goroutine/thread/task lifetimes.

  • 3 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added May 28, 2026
developmentgoexpressdebuggingapidatabaseperformance

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned May 28, 2026

npx -y skills add lugassawan/swe-workbench --skill principle-concurrency --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Principle Concurrency?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Principle Concurrency
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/lugassawan-principle-concurrency/badge)](https://www.skillsdirectory.com/skills/lugassawan-principle-concurrency)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: principle-concurrency
description: Concurrency principles — race conditions, deadlock, livelock, starvation, structured concurrency, cancellation propagation, backpressure, lock-free primitives, atomics, memory models, choosing between mutex vs channel vs actor vs semaphore vs CAS. Auto-load when designing concurrent code, debugging a race condition, fixing a deadlock, propagating cancellation, choosing a synchronization primitive, designing worker pools, or reasoning about goroutine/thread/task lifetimes.
---

# Concurrency

Concurrency is a correctness hazard first, a performance tool second. Prove correctness before optimizing.

## Failure Modes

**Race condition** — two goroutines/threads read and write shared state without synchronization; result is non-deterministic. **Fix:** mutex, channel, or atomic.

**Deadlock** — two or more tasks each hold a lock the other needs; all block forever. **Fix:** consistent lock-acquisition ordering; prefer higher-level primitives.

**Livelock** — tasks keep changing state in response to each other but make no progress; common in retry loops that back off identically. **Fix:** add jitter; use backpressure signals.

**Starvation** — a low-priority task never gets scheduled because high-priority tasks monopolize a resource. **Fix:** fair queues; priority inheritance; rate limits.

**Lost wakeup** — a condition-variable signal fires before the waiter starts waiting; waiter sleeps forever. **Fix:** always check the predicate in a loop; use atomic flags.

**ABA problem** — a CAS succeeds because a value returned to A, masking an intervening change. **Fix:** use version tags or hazard pointers; prefer higher-level data structures.

## Structured Concurrency

Child task lifetimes must nest inside the parent's lifetime. No orphan goroutines or threads.
- When the parent exits, all children are cancelled first.
- Errors propagate up — a child error surfaces to the parent, not to a background log line.
- Never fire-and-forget unless the lifetime is explicitly managed (e.g., a top-level worker pool with a shutdown hook).
- For language-specific structured concurrency APIs, see `language-go` (errgroup, context) and your platform's task group primitives.

## Cancellation

Concurrency requires cooperative cancellation — you cannot safely kill a thread mid-operation.
- Pass a context or cancellation token down the call stack; never rely on thread interruption.
- Check for cancellation at every I/O boundary and between long computation steps.
- Release resources (locks, file handles, connections) before acknowledging cancellation.
- Do not swallow cancellation signals — propagate them or translate them into a clean shutdown signal.

## Backpressure

Unbounded queues hide a broken producer/consumer balance until memory is exhausted.
- Use bounded queues with explicit drop or block policies.
- Ask "what happens when downstream is slower than upstream?" before writing any queue.
- **Drop oldest** — acceptable for telemetry and non-critical real-time data.
- **Block producer** — correct for ordered pipelines where data loss is unacceptable.
- **Error/circuit-break** — correct for RPC fan-out where partial failure is worse than full failure.

## Primitive Selection

**Mutex** — shared mutable state with exclusive access; short critical sections only.
**Use when:** multiple writers share an in-memory structure; critical section is O(1) or near.
**Costs:** lock contention serializes all callers; holding a lock across I/O causes convoy problems.

**Channel** — ownership transfer, pipeline staging, fan-out/fan-in.
**Use when:** passing a value from one goroutine/task to another; buffered for throughput, unbuffered for synchronization.
**Costs:** overhead vs mutex for simple counters; wrong buffer size silently causes deadlock.

**Actor** — state encapsulated behind a single mailbox; all access serialized through message passing.
**Use when:** complex mutable state is accessed by many concurrent callers; prefer isolation over sharing.
**Costs:** message copying overhead; harder to express synchronous request-response.

**Atomic / CAS** — lock-free fast path for counters, flags, and pointer swaps.
**Use when:** a single variable needs concurrent update; profiling shows mutex is the bottleneck.
**Costs:** memory-ordering semantics are subtle; composing multiple atomics is not itself atomic.

**Semaphore** — bounded resource pool (connection pool, worker pool, API rate limit).
**Use when:** limit concurrent access to a resource to N callers.
**Costs:** starvation possible without fair queueing.

> For Go-specific idioms (goroutine lifecycles, channel patterns, `sync` package): see `language-go`.

## When Concurrency is Overkill

- Sequential is correct until a profiler identifies a throughput or latency bottleneck.
- Single-core environments or scripts where parallelism is unavailable.
- Synchronization complexity outweighs the speedup — measure first.

## Red Flags

| Flag | Problem |
|------|---------|
| `sleep` used to synchronize goroutines or threads | Sleep-based sync is a race condition with a timing window; use channels or barriers |
| Double-checked locking without atomics or memory fences | Compilers and CPUs reorder; the outer check is not safe without proper memory ordering |
| Unbounded channel or queue | Hides backpressure; exhausts memory under sustained load |
| Lock held across a network call or database query | Serializes all callers for the full I/O duration; severe performance cliff |
| Race "fixed" by adding more locks | Deadlock risk grows with lock count; redesign ownership instead |

Files in this skill

  • SKILL.md5.5 KB
  • triggers.txt544 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.