J'ai lu beaucoup d'articles en ligne et je suis toujours confus. Quelqu'un peut-il m'expliquer ces deux concepts d'une manière facile à comprendre ?
Dans le codage multi-thread Python, j'utilise généralement une boucle infinie while True dans la méthode d'exécution du thread, puis j'appelle queue.task_done à la fin du corps de la boucle infinie pour supprimer la file d'attente, puis j'appelle la file d'attente. Méthode join dans le thread principal à bloquer. Le thread principal empêche le thread principal de se terminer directement. Cette méthode de codage multithread est-elle raisonnable ? Y aura-t-il des bugs ? De plus, je voudrais demander si la boucle infinie que j'appelle en run s'appelle un spin lock ?
Tout d'abord, vous devez comprendre ce qu'est un verrou mutex et ce qu'il signifie
C'est lorsque deux threads A et B accèdent à la même mémoire.
Idéalement, notre ordre d'exécution devrait être qu'une fois A complètement exécuté, B sera exécuté. Cependant, l'exécution occupera le temps d'instruction du CPU. Si aucun mécanisme n'est utilisé, lorsque A est à mi-chemin, B occupera le CPU et. B occupera le CPU. Pour traiter cette mémoire, alors B termine l'exécution et A récupère le CPU, les données de la mémoire ne seraient-elles pas fausses ?
Pour la sécurité des données de la mémoire. Une technologie mutuellement exclusive est utilisée. Lorsque A accède à cette mémoire, il détermine d'abord si cette mémoire a un indicateur en cours d'utilisation (appelé verrou). Sinon, il ajoute un indicateur (verrou) à cette mémoire, alors A le traite. mémoire, et A la déverrouille après le traitement. Si B accède pendant que A traite la mémoire, B verra que cette mémoire a un signe d'utilisation (verrouillage), et B peut avoir plusieurs comportements. Comportement 1 : utilisation du processeur. Bouclez et testez en continu l'état du verrou. Le thread ne se bloquera pas (en veille) et est dans un état d'attente occupé. Un verrou qui adopte ce comportement est appelé un verrou tournant. Comportement 2 : le thread B dort et se bloque, abandonnant le processeur jusqu'à ce que A termine son exécution et que le verrou disparaisse, puis utilise la mémoire. Ce comportement est appelé verrouillage mutex. Après avoir vu cela, vous comprenez probablement que les verrous sont des mécanismes de synchronisation qui mettent en œuvre une exclusion mutuelle. Un verrou tournant n'est qu'un cas de verrou mutex (il occupera le verrou mutex du processeur en attendant).
Ne vous laissez pas tromper par le nom. Pour comprendre le mécanisme derrière cela, vous devez le comprendre même si vous changez le nom,
Lien de référence Description du lien
1. Lors de l'utilisation d'une boucle while dans la méthode d'exécution multithread Python, si le mécanisme d'arrêt du programme n'est pas utilisé dans le corps de la boucle, il continuera à s'exécuter. Par conséquent, si l'affiche veut coder correctement, il peut utiliser un. sémaphore ou autre mécanisme variable pour notifier le corps de la boucle, ou déterminer si la file d'attente est vide, interrompez directement et quittez la boucle.
2. La boucle infinie en cours d'exécution n'est pas un verrou de rotation. S'il y a une concurrence de ressources au sein de la boucle, un verrou est ajouté, mais ce verrou est également un verrou d'exclusion mutuelle.
Le verrou de Python utilise le sémaphore, pas le spinlock.
Verrouillage rotatif : plusieurs threads accèdent à la même ressource en même temps. Il s'agit d'un verrou défini pour empêcher la lecture et la modification incohérentes des ressources. Si un thread occupe déjà la ressource lorsqu'un thread accède à la ressource, alors ce dernier thread attendra. le thread actuel pour libérer la ressource. À ce moment, ce dernier (sans dormir) continue d'exécuter le CPU pour détecter si les ressources occupées par le premier sont libérées. Le mécanisme par lequel ce dernier accède et détecte en permanence l'occupation des ressources est le spin lock. .
Verrou Mutex : Le but est le même que le verrou tournant, mais le mécanisme est différent Lorsque le thread occupe la ressource, un verrou est ajouté. Lorsque ce dernier thread accède à la ressource, il entre en état de veille car la ressource est occupée. , et attend que la ressource soit libérée. Enfin, les threads en attente sont avertis via le sémaphore.
Le code Python s'exécutera selon ce processus,
Configurer GIL
Passer à un certain fil de discussion
Courir
Le fil se ferme et passe en mode veille
Débloquez GIL
Répétez les opérations ci-dessus
Peut-être à cause de GIL, je ne semble pas avoir vu de verrous tournants en Python, et les verrous mutex sont principalement utilisés.
Voici la méthode que j'ai utilisée pour écrire du multi-threading, pour référence seulement~
Puisqu'il s'agit d'une file d'attente, Queue().get() dans Queue explique Supprimer et renvoyer un élément de la file d'attente.