Maison > développement back-end > Golang > 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
Libérer: 2024-10-31 00:31:29
original
1018 Les gens l'ont consulté

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>
Copier après la connexion

Verrouillage :

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

<code class="go">l <- struct{}{}</code>
Copier après la connexion

Déverrouillage :

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

<code class="go"><-l</code>
Copier après la connexion

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>
Copier après la connexion

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>
Copier après la connexion

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>
Copier après la connexion

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>
Copier après la connexion

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!

source:php.cn
Déclaration de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal