Maison  >  Article  >  développement back-end  >  Comment implémenter le verrouillage avec délais d'attente dans Go à l'aide de canaux ?

Comment implémenter le verrouillage avec délais d'attente dans Go à l'aide de canaux ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-10-31 00:31:29936parcourir

How to Implement Locking with Timeouts in Go using Channels?

Verrouillage avec délais d'attente dans Go

Défi :

L'acquisition de verrous dans Go peut être problématique, en particulier lorsqu'il s'agit de latence -opérations sensibles. L'interface sync.Mutex fournit uniquement des fonctions de verrouillage et de déverrouillage de base sans possibilité d'acquérir des verrous sous condition ou dans un délai spécifié.

Solution :

Utiliser des canaux comme Mutex :

Une solution simple et efficace consiste à utiliser les canaux comme primitives d'exclusion mutuelle. En créant un canal avec une taille de buffer de un, vous pouvez simuler un verrou :

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

Verrouillage :

Pour acquérir le verrou, envoyez un signal au chaîne :

<code class="go">l <- struct{}{}</code>

Déverrouillage :

Pour déverrouiller le verrou, recevez de la chaîne :

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

Essayez le verrouillage :

Pour tenter un verrouillage avec un délai d'attente, utilisez une instruction select :

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

En combinant cette approche avec time.After(), vous pouvez implémenter TryLock avec un délai :

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

Exemple 1 : Limitation des opérations sensibles à la latence

<code class="go">func (s *RPCService) DoTheThing(ctx context.Context, ...) ... {
  if AcquireLock(ctx.Deadline(), &s.someObj[req.Parameter].lock) {
    defer ReleaseLock(&s.someObj[req.Parameter].lock)
    ... expensive computation ...
  } else {
    return s.cheapCachedResponse[req.Parameter]
  }
}</code>

Exemple 2 : Mise à jour des statistiques avec délai d'attente

<code class="go">func (s *StatsObject) updateObjStats(key, value interface{}) {
  if AcquireLock(200*time.Millisecond, &s.someObj[key].lock) {
    defer ReleaseLock(&s.someObj[key].lock)
    ... update stats ...
    ... fill in s.cheapCachedResponse ...
  }
}

func (s *StatsObject) UpdateStats() {
  s.someObj.Range(s.updateObjStats)
}</code>

Cette approche vous permet d'acquérir des verrous de manière conditionnelle tout en gérant efficacement les problèmes de performances et d'utilisation des ressources.

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