Maison >développement back-end >Golang >Comment acquérir un verrou avec une date limite en Go ?

Comment acquérir un verrou avec une date limite en Go ?

Patricia Arquette
Patricia Arquetteoriginal
2024-10-29 15:22:02648parcourir

How to Acquire a Lock with a Deadline in Go?

Acquisition du verrouillage avec date limite dans Go

Dans Go, le type sync.Mutex ne fournit que les méthodes Lock() et Unlock(). Pour les scénarios dans lesquels une acquisition de verrou doit être tentée dans un délai donné, ou potentiellement interrompue immédiatement, il n'existe pas de solution intégrée.

Solution proposée : canaliser en tant que Mutex

Une approche alternative consiste à utiliser un canal avec une taille de tampon de un pour simuler un mutex. En envoyant et en recevant une seule valeur de structure vide (struct{}{}), des opérations de verrouillage et de déverrouillage peuvent être effectuées.

Verrouillage :

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

Déverrouiller :

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

Essayer de verrouiller :

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

Essayer de verrouiller avec délai d'attente :

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

Dans les exemples fournis, s.someObj est supposé être une carte de clé à valeur.

Exemple 1 : LockBefore() pour le code sensible à la latence

<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>

Exemple 2 : TryLock() pour la mise à jour des statistiques

<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>

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn