À partir de la documentation Gevent:
Les greenlets s'exécutent tous dans le même thread du système d'exploitation et sont planifiés en coopération.
Alors est-il toujours nécessaire d'utiliser les primitives de verrouillage gevent ou gevent.Queue pour éviter les conditions de concurrence entre plusieurs greenlets dans un seul thread? Un exemple pour démontrer une telle condition de course serait très apprécié. D'après ma propre compréhension, ces primitives de synchronisation semblent être juste un moyen de changer le flux d'exécution entre les greentlets.
Oui, en général, il est toujours nécessaire d'utiliser des constructions de verrouillage et de synchronisation dans gevent.
Les constructions de verrouillage et de synchronisation, sous les threads et gevent, telles que RLock, Semaphore et Queue sont là pour garantir que l'état du programme est cohérent en interne en protégeant l'accès aux données critiques ou aux sections de code critiques (en fait, en prétendant qu'une telle section ou un tel élément de données fonctionne tout seul).
La différence entre les greenlets et le threading est que si un changement de contexte de thread peut théoriquement se produire à tout moment hors de votre contrôle, un changement de contexte de greenlet ne peut se produire qu'à des moments spécifiques définis, et donc théoriquement, si vous êtes très prudent dans votre programmation et avoir un contrôle complet sur la façon dont la section ou les données critiques sont utilisées, vous pouvez éviter complètement les commutateurs et éliminer le besoin de verrous. Parfois, cela est facile à faire, parfois non, selon le programme. Dans gevent, lorsque les E / S, time.sleep()
etc., peuvent tous provoquer des commutations, s'il y a beaucoup de complexité du code, il peut être difficile d'être entièrement sûr qu'il n'y aura pas de commutateurs, donc les règles standard de synchronisation et de verrouillage sont les meilleures.
Voici un exemple. Disons que nous voulons écrire des messages (données structurées) dans un fichier ou un objet semblable à un fichier. Imaginons que les messages soient rassemblés en continu, un morceau à la fois, mais que le destinataire doit être capable de lire le message ensemble en un seul morceau --- l'interconnexion de morceaux de deux messages différents entraîne un désordre brouillé.
def generate_data(chunks):
# This task generates the data that makes up a message
# in chunks.
# Imagine that each chunk takes some time to generate.
# Maybe we're pulling data from a database.
for chunk in chunks:
yield chunk
def worker_one(file):
file.write("begin message")
for chunk in generate_data('abcde'):
file.write(chunk)
file.write("end message")
def worker_two(file):
file.write("begin message")
for chunk in generate_data('123456'):
file.write(chunk)
file.write("end message")
output_file = get_output_file()
workers = [gevent.spawn(worker_one, output_file),
gevent.spawn(worken_two, output_file)]
gevent.joinall(workers)
Si cela get_output_file
revient simplement open('/some/file')
, cela fonctionnera bien: l'utilisation d'un file
objet normal ne coopère pas avec la boucle gevent, et donc chaque worker fonctionnera jusqu'à la fin sans jamais céder et les messages seront intacts.
Cependant, s'il retournait socket.create_connection(("some.host", 80)).makefile()
, cela échouerait et les messages seraient fragmentés. Chaque écriture sur le socket d'un worker pourrait laisser le greenlet se produire et l'autre greenlet s'exécuter, ce qui entraînerait des données brouillées.
Si generate_data
c'était plus complexe, peut-être communiquer avec un serveur ou une base de données via une socket gevent, alors même si nous écrivions dans un fichier, les messages pourraient être déformés car les greenlets ont basculé pendant le processus de génération de données.
Ceci est un exemple de la raison pour laquelle l'état partagé (dans ce cas, le socket) peut avoir besoin d'être protégé avec des constructions de synchronisation.
Cet article est collecté sur Internet, veuillez indiquer la source lors de la réimpression.
En cas d'infraction, veuillez [email protected] Supprimer.
laisse moi dire quelques mots