circular wait
Think of four children passing a single ball each, sitting in a ring. Each child says 'I will give you my ball as soon as you give me yours' — but speaks to the child on their left, while expecting from the child on their right. Around the whole circle everyone is waiting on the next person, and the chain closes back on itself, so no one ever hands anything over. That closed loop of mutual waiting is circular wait.
Circular wait is the fourth necessary condition for deadlock and, intuitively, the one that 'seals' the trap. It holds when there is a set of waiting processes P1, P2, ..., Pn such that P1 is waiting for a resource held by P2, P2 is waiting for one held by P3, and so on, with Pn waiting for a resource held by P1 — a cycle. In the resource-allocation graph this is literally a cycle of edges through processes and resources. The classic prevention is to impose a TOTAL ORDERING on all resource types — number them 1, 2, 3, ... — and require that every process acquire resources only in increasing order. Then no cycle can ever form, because a cycle would need some process holding a higher-numbered resource while requesting a lower-numbered one, which the rule forbids.
Lock-ordering is the everyday, practical version of this idea and is the single most common real-world defense against deadlock in concurrent code: agree on a global order for your locks and always take them in that order. The honest caveat is twofold. First, the ordering must be GLOBAL and consistent — one function that grabs locks in the wrong order can reintroduce a cycle. Second, a cycle in the wait graph is a guaranteed deadlock only with single-instance resources; with multiple instances a cycle is necessary but not sufficient, because a spare instance might break the chain.
Without ordering: thread X does lock(A); lock(B) while thread Y does lock(B); lock(A) — a cycle is possible. With ordering (A before B always): both do lock(A); lock(B), so neither can hold B while waiting for A, and no cycle can form.
A global acquisition order on resources makes circular wait impossible.
A cycle in the wait graph guarantees deadlock only when every resource is single-instance; with multiple instances a cycle is necessary but not sufficient. The ordering defense fails if it is not applied globally and consistently.