« Programmation Python/Threads » : différence entre les versions

Contenu supprimé Contenu ajouté
DannyS712 (discussion | contributions)
m <source> -> <syntaxhighlight> (phab:T237267)
Ligne 36 :
Le script ci-après définit le programme client. Vous constaterez que la partie principale du script (ligne 38 et suivantes) est similaire à celle de l'exemple précédent. Seule la partie « Dialogue avec le serveur » a été remplacée. Au lieu d'une boucle <code>while</code>, vous y trouvez à présent les instructions de création de deux objets threads (aux lignes 49 et 50), dont on démarre la fonctionnalité aux deux lignes suivantes. Ces objets threads sont créés par dérivation, à partir de la classe <code>Thread()</code> du module ''threading''. Ils s'occuperont indépendamment de la réception et de l'émission des messages. Les deux threads « enfants » sont ainsi parfaitement encapsulés dans des objets distincts, ce qui facilite la compréhension du mécanisme.
 
<sourcesyntaxhighlight lang=python line>
# Définition d'un client réseau gérant en parallèle l'émission
# et la réception des messages (utilisation de 2 THREADS).
Ligne 89 :
th_E.start()
th_R.start()
</syntaxhighlight>
</source>
 
;Commentaires
Ligne 117 :
Ce serveur n'est pas utilisé lui-même pour communiquer : ce sont les clients qui communiquent les uns avec les autres, par l'intermédiaire du serveur. Celui-ci joue donc le rôle d'un relais : il accepte les connexions des clients, puis attend l'arrivée de leurs messages. Lorsqu'un message arrive en provenance d'un client particulier, le serveur le ré-expédie à tous les autres, en lui ajoutant au passage une chaîne d'identification spécifique du client émetteur, afin que chacun puisse voir tous les messages, et savoir de qui ils proviennent.
 
<sourcesyntaxhighlight lang=python line>
# Définition d'un serveur réseau gérant un système de CHAT simplifié.
# Utilise les threads pour gérer les connexions clientes en parallèle.
Ligne 176 :
# Dialogue avec le client :
connexion.send("Vous êtes connecté. Envoyez vos messages.")
</syntaxhighlight>
</source>
 
;Commentaires
Ligne 227 :
Voici un exemple de dialogue type, tel qu'il peut être suivi du côté d'un client. Les messages entre astérisques sont ceux qui sont reçus du serveur ; les autres sont ceux qui sont émis par le client lui-même :
 
<sourcesyntaxhighlight lang=text line>
*serveur OK*
client OK
Ligne 245 :
*départ_de,Thread-2*
*nouveau_canon,Thread-5,502,276,-1,dark green*
</syntaxhighlight>
</source>
 
Lorsqu'un nouveau client démarre, il envoie une requête de connexion au serveur, lequel lui expédie en retour le message : « serveur OK ». À la réception de ce dernier, le client répond alors en envoyant lui-même : « client OK ». Ce premier échange de politesses n'est pas absolument indispensable, mais il permet de vérifier que la communication passe bien dans les deux sens. Étant donc averti que le client est prêt à travailler, le serveur lui expédie alors une description des canons déjà présents dans le jeu (éventuellement aucun) : identifiant, emplacement sur le canevas, orientation et couleur (ligne 3).
Ligne 269 :
Vous trouverez dans les pages qui suivent le script complet du programme serveur. Nous vous le présentons en trois morceaux successifs afin de rapprocher les commentaires du code correspondant, mais la numérotation de ses lignes est continue. Bien qu'il soit déjà relativement long et complexe, vous estimerez probablement qu'il mérite d'être encore perfectionné, notamment au niveau de la présentation générale. Nous vous laisserons le soin d'y ajouter vous-même tous les compléments qui vous sembleront utiles (par exemple, une proposition de choisir les coordonnées de la machine hôte au démarrage, une barre de menus, etc.) :
 
<sourcesyntaxhighlight lang=python line>
#######################################################
# Jeu des bombardes - partie serveur #
Ligne 326 :
self.regl.set(angle)
self.regl.config(state =DISABLED)
</syntaxhighlight>
</source>
 
La classe <code>Pupitre()</code> est construite par dérivation de la classe de même nom importée du modune ''canon03''. Elle hérite donc toutes les caractéristiques de celle-ci, mais nous devons surcharger<ref>Rappel : dans une classe dérivée, vous pouvez définir une nouvelle méthode avec le même nom qu'une méthode de la classe parente, afin de modifier sa fonctionnalité dans la classe dérivée. Cela s'appelle surcharger cette méthode</ref> ses méthodes <code>tirer()</code> et <code>orienter()</code> :
Ligne 338 :
La classe <code>ThreadConnexion()</code> ci-dessous sert à instancier la série d'objets threads qui s'occuperont en parallèle de toutes les connexions lancées par les clients. Sa méthode <code>run()</code> contient la fonctionnalité centrale du serveur, à savoir la boucle d'instructions qui gère la réception des messages provenant d'un client particulier, lesquels entraînent chacun toute une cascade de réactions. Vous y trouverez la mise en œuvre concrète du protocole de communication décrit dans les pages précédentes.
 
<sourcesyntaxhighlight lang=python line start=58>
 
class ThreadConnexion(threading.Thread):
Ligne 419 :
self.app.afficher("Client %s déconnecté.\n" % nom)
# Le thread se termine ici
</syntaxhighlight>
</source>
 
=== Synchronisation de threads concurrents à l'aide de « verrous » (thread locks) ===
Ligne 451 :
La classe <code>AppServeur()</code> dérive de la classe <code>AppBombardes()</code> du module ''canon04''. Nous lui avons ajouté un ensemble de méthodes complémentaires destinées à exécuter toutes les opérations qui résulteront du dialogue entamé avec les clients. Nous avons déjà signalé plus haut que les clients instancieront chacun une version dérivée de cette classe (afin de profiter des mêmes définitions de base pour la fenêtre, le canevas, etc.).
 
<sourcesyntaxhighlight lang=python line start=138>
class ThreadClients(threading.Thread):
"""objet thread gérant la connexion de nouveaux clients"""
Ligne 597 :
if __name__ =='__main__':
AppServeur(host, port, largeur, hauteur).mainloop()
</syntaxhighlight>
</source>
 
;Commentaires
Ligne 621 :
C'est dans la méthode <code>run()</code> de la classe <code>ThreadSocket()</code> (lignes 86 à 126) que se trouve le code traitant les messages échangés avec le serveur. Nous y avons d'ailleurs laissé une instruction print (à la ligne 88) afin que les messages reçus du serveur apparaissent sur la sortie standard. Si vous réalisez vous-même une forme plus définitive de ce jeu, vous pourrez bien évidemment supprimer cette instruction.
 
<sourcesyntaxhighlight lang=python line>
#######################################################
# Jeu des bombardes - partie cliente #
Ligne 765 :
if __name__ =='__main__':
AppClient(host, port, largeur, hauteur).mainloop()
</syntaxhighlight>
</source>
 
;Commentaires
Ligne 1 022 :
[[Image:Apprendre à programmer avec Python 71.png|center|capture d'écran de l'application]]
 
<sourcesyntaxhighlight lang=python line>
from Tkinter import *
from math import sin, cos
Ligne 1 059 :
 
App().mainloop()
</syntaxhighlight>
</source>
 
;Commentaires