Home >Backend Development >Golang >How to Acquire a Lock with a Deadline in Go?

How to Acquire a Lock with a Deadline in Go?

Patricia Arquette
Patricia ArquetteOriginal
2024-10-29 15:22:02685browse

How to Acquire a Lock with a Deadline in Go?

Acquiring Lock with Deadline in Go

In Go, the sync.Mutex type only provides Lock() and Unlock() methods. For scenarios where a lock acquisition should be attempted within a deadline, or potentially aborted immediately, there is no built-in solution.

Proposed Solution: Channel as Mutex

An alternative approach is to use a channel with a buffer size of one to simulate a mutex. By sending and receiving a single empty struct value (struct{}{}), lock and unlock operations can be performed.

Lock:

<code class="go">l := make(chan struct{}, 1)
l <- struct{}{}</code>

Unlock:

<code class="go"><-l</code>

Try Lock:

<code class="go">select {
case l <- struct{}{}:
    // lock acquired
    <-l
default:
    // lock not acquired
}</code>

Try Lock with Timeout:

<code class="go">select {
case l <- struct{}{}:
    // lock acquired
    <-l
case <-time.After(time.Minute):
    // lock not acquired
}</code>

In the provided examples, s.someObj is assumed to be a map from key to value.

Example 1: LockBefore() for Latency Sensitive Code

<code class="go">// DoTheThing locks before performing expensive computations.
func (s *RPCService) DoTheThing(ctx context.Context, ...) ... {
    l := make(chan struct{}, 1)
    select {
    case l <- struct{}{}:
        defer <-l
        ... expensive computation based on internal state ...
    default:
        return s.cheapCachedResponse[req.Parameter]
    }
}</code>

Example 2: TryLock() for Updating Stats

<code class="go">// updateObjStats attempts to lock and update stats.
func (s *StatsObject) updateObjStats(key, value interface{}) {
    l := make(chan struct{}, 1)
    select {
    case l <- struct{}{}:
        defer <-l
        ... update stats ...
        ... fill in s.cheapCachedResponse ...
    default:
        // skip locked object
    }
}

// UpdateStats attempts to lock and update stats for all objects.
func (s *StatsObject) UpdateStats() {
    s.someObj.Range(s.updateObjStats)
}</code>

The above is the detailed content of How to Acquire a Lock with a Deadline in Go?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn