For the classic single-producer / single-consumer case, one writer (the ISR) that only ever advances head, one reader (the main loop) that only ever advances tail, you can make it lock-free, no critical section needed, if you're careful. The key is that each index has exactly one writer: the producer owns head, the consumer owns tail, and each side only reads the other's index. As long as index reads/writes are atomic (a single aligned word on the MCU, which a volatile uint32_t index is on a 32-bit core) and you publish the data before advancing the index the other side keys off, each observer sees a consistent view: the consumer never reads a slot until head has moved past it, and the producer never overwrites a slot until tail has freed it. That last point matters, memory ordering: on a core with a weak memory model or an aggressive compiler you need a barrier (or C11 atomics with acquire/release, or at minimum volatile plus a DMB) so the data write isn't reordered after the index update. The moment you have multiple producers or multiple consumers, the single-writer-per-index invariant breaks and you do need a lock (or disabling interrupts around the shared index). So: SPSC ring buffer, no lock but mind the barrier; anything else, protect it.
Data Structures & Algorithms · Interview question
An ISR enqueues bytes into a ring-buffer queue and the main loop dequeues them. Do you need a lock?
A strong answer
What a weak answer sounds like
You know the answer. Do you know what gets you dinged?
Pro breaks down the answer most candidates actually give to this question — and the specific reason an interviewer marks it down. It’s the difference between sounding correct and sounding senior, on all 472 questions.
From the lesson
Stacks & Queues
LIFO stacks and FIFO queues: the two access disciplines behind the call stack, expression evaluation, and ISR-to-main event passing, and how to back each with fixed memory.
More Stacks & Queues questions
What's the difference between a stack and a queue?How would you implement a queue efficiently, and what's the naive mistake?Give a concrete embedded use for a stack and one for a queue.What does "peek" do, and why does the distinction from "pop" matter?What bounds must you check on a fixed-capacity stack or queue?How would you implement a FIFO queue using only two stacks, and what's the cost?
Browse all 472 interview questions