Spin locks, sémaphores, mutex, complétions sous linux

       La concurrence et la concurrence sont relativement faciles à se produire sous Linux. Les opérations atomiques ne peuvent être effectuées que sur des nombres entiers. Par conséquent, les mutex et les verrous tournants sont souvent utilisés pour protéger les ressources critiques afin de résoudre les problèmes de concurrence et de concurrence.

Utilisation du mutex et du spinlock :

       Dans le contexte du processus, un mutex peut être utilisé pendant un temps de maintien long, car il peut dormir, et un verrou tournant peut être utilisé pendant un temps de maintien court pour réduire le temps de changement de contexte. Les verrous rotatifs peuvent être utilisés dans des contextes d'interruption, mais les mutex ne peuvent pas être utilisés car ils peuvent dormir. Cependant, avant que le contexte d'interruption n'acquière le verrou tournant, l'interruption locale doit être désactivée pour empêcher l'imbrication des interruptions. Le code avec des spinlocks ne peut pas dormir et ne peut pas être utilisé de manière récursive, sinon il provoquera un blocage.

Montant du signal :

Le sémaphore est le moyen le plus typique utilisé par le système d'exploitation pour l'exclusion mutuelle et la synchronisation, et sa valeur peut être 0, 1 ou n. L'opération P et l'opération V peuvent être effectuées, et ce sont également des opérations atomiques, qui ne seront pas interrompues pendant l'exécution.

P(s) : Décrémentez 1 de la valeur de s, si s >= 0, le processus continue à s'exécuter, sinon placez le processus dans un état d'attente, entrez en veille et rejoignez la file d'attente. C'est-à-dire l'opération vers le bas

V(s) : Ajouter 1 à la valeur de s, si s > 0, réveille le processus en attente du sémaphore dans la file d'attente. C'est-à-dire l'opération UP.

  • struct semaphore sem ; la définition de sémaphore
  • void sema_init(struct semaphore *sem, int val) : Initialise et définit la valeur du sémaphore sem sur val.
  • void down (struct semaphore *sem ); le sémaphore est décrémenté de 1, il va dormir et ne peut pas être utilisé dans le contexte d'interruption.
  • int down_interruptibleistruet sémaphore * sem); est cohérent avec la fonction down, mais le processus d'entrée dans l'état de veille peut être interrompu par le signal, et le signal provoquera également le retour de la fonction. À ce moment, la valeur de retour de la fonction n'est pas 0.
  • int down_trylock (struct semaphore* sem); Cette fonction essaie d'obtenir le sémaphore sem. S'il peut être obtenu immédiatement, il obtiendra le sémaphore et renverra 0, sinon, renverra une valeur différente de zéro. Il ne met pas l'appelant en veille et peut être utilisé dans un contexte d'interruption.
  • vaid up (struct semaphore * sem ) Libère le sémaphore sem et réveille le serveur.

Lorsqu'il est utilisé comme exclusion mutuelle, processus 1 : P(s)--->section critique--->V(s). Mais le noyau Linux préfère le mutex comme moyen d'exclusion mutuelle.

Lorsqu'il est utilisé comme synchronisation : ---> Le processus 1 s'exécute vers le bas (p) et attend ----> Le processus 2 : vers le haut (v) -----> Le processus 1 s'exécute :

processus 1 processus 2
vers le bas (p) le code
attendez vers le haut (v)
le code

verrou tournant :

        Le verrouillage de rotation est un moyen typique d'exclusion mutuelle des ressources critiques. Afin d'obtenir un verrou tournant, une opération atomique sera d'abord exécutée sur un certain processeur. Cette opération consiste à tester et à définir une certaine variable de mémoire. Le résultat du test indique que le verrou est libre. Le programme obtient le verrou tournant et continue pour exécuter des ressources critiques, telles que Le résultat du test indique qu'il est occupé, et le programme tournera en rond, obtenant de manière récursive en continu si le verrou est libre, jusqu'à ce que le verrou soit libre, puis continue à exécuter des ressources critiques.

  • spinlock_t lock ; //Définir le verrou tournant
  • spin_lock_init (lock) //Initialise le verrou tournant
  • spin_lock (lock) //Obtenez le verrou de rotation et revenez immédiatement, sinon il tournera jusqu'à ce qu'il soit relâché et revienne
  • spin_unlock (lock) // relâche le verrou tournant

Mutex :

L'exclusion mutuelle des ressources critiques est une méthode courante d'exclusion mutuelle dans le noyau Linux. C'est la même chose que l'exclusion mutuelle du sémaphore, et il dormira après l'exclusion mutuelle. L'utilisation est cohérente avec l'exclusion mutuelle du sémaphore, et elle est utilisée dans le contexte du processus.

  • struct mutex my_mute // définition du mutex
  • mutex_init{&my_mutex.); //Initialisation
  • void mutex_lock(struct mutex *lock); // Récupère le mutex
  • void mutex_unlock(struct mutex*lock); // libère le mutex

Montant réalisé :

Le rôle de la quantité d'achèvement peut être utilisé pour la synchronisation. Un processus attend qu'un autre processus termine une tâche avant de continuer à s'exécuter :

  • struct Completion my_completion ; // définition du montant de l'achèvement
  • init_completion ( &my_completion); // Initialise le montant de l'achèvement, la valeur initiale est 0
  • void wait_for_completion (struct Completion *c); // attend que l'achèvement soit réveillé
  • void complete (struct Completion *e); // Il est temps de se réveiller
  processus 1 processus 2
le code attendre_la_complétion
complet  ....attendez
continuer à exécuter

Je suppose que tu aimes

Origine blog.csdn.net/weixin_42432281/article/details/126286520
conseillé
Classement