How to Implement Non‑Reentrant Functions in Go: Mutex and Atomic Solutions
This article explains what a non‑reentrant function is, why it matters in concurrent Go programs, and demonstrates two practical implementations—using a sync.Mutex and an atomic flag—to ensure a function runs only once at any given time.
What Is a Non‑Reentrant Function?
A non‑reentrant function can be executed only once at any point in time, regardless of how many times it is called or how many goroutines invoke it.
Scenario
A service polls certain conditions every second and checks multiple statuses concurrently. Each status check is fast, but if CheckAnotherStatus() takes longer than a second, overlapping executions may occur, which we want to avoid.
Blocking (Mutex) Solution
The simplest way to prevent concurrent executions is to protect the critical section with sync.Mutex . The lock is acquired before calling CheckAnotherStatus() and released afterward.
<code>import (
"sync"
"time"
)
func main() {
tick := time.Tick(time.Second)
var mu sync.Mutex
go func() {
for range tick {
go CheckSomeStatus()
go func() {
mu.Lock()
defer mu.Unlock()
CheckAnotherStatus()
}()
}
}()
}
</code>This code guarantees that only one goroutine can execute CheckAnotherStatus() at a time; subsequent loop iterations block on the mutex.
Yielding (Atomic) Solution
When many calls may pile up, a yielding approach can be more efficient. An int64 flag is used with sync/atomic to allow at most one execution; extra calls simply return.
<code>import (
"sync/atomic"
"time"
)
func main() {
tick := time.Tick(time.Second)
var reentranceFlag int64
go func() {
for range tick {
go CheckSomeStatus()
go func() {
if atomic.CompareAndSwapInt64(&reentranceFlag, 0, 1) {
defer atomic.StoreInt64(&reentranceFlag, 0)
} else {
return
}
CheckAnotherStatus()
}()
}
}()
}
</code>The atomic CompareAndSwapInt64 succeeds only when the flag is zero, setting it to one for the duration of the function. When the function finishes, the flag is reset, allowing the next call.
Summary
Both approaches move the non‑reentrancy logic outside the business function; the mutex version blocks subsequent calls, while the atomic version silently skips them. Either method can be adapted to other languages or to use int32 instead of int64 when appropriate.
360 Zhihui Cloud Developer
360 Zhihui Cloud is an enterprise open service platform that aims to "aggregate data value and empower an intelligent future," leveraging 360's extensive product and technology resources to deliver platform services to customers.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.