Partage de variable entre les threads

Résolu
Bonjour,

J'essaie de réaliser un serveur qui récupère des données via liaison UDP et qui les transmet à plusieurs clients web via websockets.
J'utilise pour cela les threads, un pour récupérer les données UDP et d'autres pour chaque client connecté (pour l'instant il n'y en a qu'un)

Je stocke alors les données reçues dans la variable "msg_gnuradio" dans le premier thread et je souhaite l'envoyer vers le client dans le second thread avec websocket.send().


#Ajout des librairies :

import socket #pour les sockets
import websockets #pour les websockets
import asyncio #pour les fonctions asynchrones (qui s'execute dans n'importe quel ordre)
import time #pour le sleep()
from threading import Thread

msg_gnuradio = "o"

#Fonction liée au thread UDP
def listen_udp():
len_data = 1024
#Création socket UDP
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

#Lier la socket à l'adress IP et le port
s.bind(('localhost', 1234))
print("Serveur UDP à l'écoute")

while(True):

addr = s.recvfrom(len_data)
msg_gnuradio = format(addr)
# print(msg_gnuradio)
time.sleep(1)

#Fonction liée au thread WEB
async def listen_ws(websocket, path):
try:
print("fonction listen_ws")
msg_client = await websocket.recv()
print("< " + msg_client)
i = 0
while True:
try:
await websocket.send(format(i)+" : "+msg_gnuradio)
# print("> datas envoyées")
time.sleep(1)
i = i+1
except KeyboardInterrupt:
print("Exiting program...")
finally:
await websocket.send("Le serveur n'est pas connecté à GNURadio")

def start_loop(loop, server):
loop.run_until_complete(server)
loop.run_forever()

#Lancement Thread UDP
udp = Thread(target=listen_udp) #Création thread pour l'UDP
udp.start()

# start a new event loop
new_loop = asyncio.new_event_loop()

#Lancement Thread WEB
port_websockets = 8000 #port pour les connexions websocket
nb_clients = 0 #nombre de clients connecté
start_server = websockets.serve(listen_ws, "localhost", port_websockets, loop=new_loop)
web = Thread(target=start_loop, args=(new_loop, start_server))
web.start()
print("Serveur websocket à l'écoute sur le port " + str(port_websockets))

for i in range(10):
print(i)
time.sleep(2)


Le problème est que la variable msg_gnuradio ne s'actualise que dans le thread UDP (on le voit bien si je l'affiche sur la console) mais dans le thread websocket elle n'est pas modifiée et j'envoie toujours "o" vu que c'est ce que j'ai initialisé.

J'ai essayé plusieurs méthodes en utilisant "global" mais cela ne fonctionne pas ou bien je ne l'utilisait pas correctement...

Pouvez-vous m'aider s'il vous plait ?

Merci d'avance

2 réponses

  1. Contributeur
    bonjour,
    Peux-tu montrer comment tu as utilisé "global"?
    Peux-tu préciser le langage quand tu utilises les balises de code? https://codes-sources.commentcamarche.net/faq/11288-les-balises-de-code
    1. Bonjour,

      D'accord j'y penserai la prochaine fois pour le code..

      J'ai utilisé le terme global dans la fonction listen_udp pour déclarer la variable à l'intérieur mais j'ai eu une erreur "d'intdentation" alors je me suis dit que ça ne devait pas se placer ici.

      J'ai essayé un peu partout après, sans succès...
    2. Contributeur
      @TR_2000Tu n'as donc pas correctement mis global, ce qui explique le comportement observé.
      Peux-tu montrer le code avec
      global
      , et l'erreur obtenue?
      Il est préférable de mettre
      global
      dans chacune des fonctions utilisant la variable.
    3. @yg_beVoici le code avec la variable global msg_gnuradio dans les 2 fonctions :

      #Ajout des librairies :
      
      import socket 			#pour les sockets	
      import websockets 		#pour les websockets  
      import asyncio    		#pour les fonctions asynchrones (qui s'execute dans n'importe quel ordre)		
      import time				#pour le sleep()	
      from threading import Thread
      
      
      #Fonction liée au thread UDP 
      def listen_udp():
      	len_data = 1024
      	#Création socket UDP
      	s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
      
      	#Lier la socket à l'adress IP et le port
      	s.bind(('localhost', 1234))
      	print("Serveur UDP à l'écoute")
          global msg_gnuradio
      	while(True):
      
      		addr = s.recvfrom(len_data)
      		msg_gnuradio = format(addr)
      		# print(msg_gnuradio)
      		time.sleep(1)
      
      
      #Fonction liée au thread WEB 
      async def listen_ws(websocket, path):
          try:
              msg_client = await websocket.recv()
              print("< " + msg_client)
              i = 0
              global msg_gnuradio
              while True:
                  try:
                      await websocket.send(format(i)+" : "+msg_gnuradio)
                      # print("> datas envoyées")
                      time.sleep(1)
                      i = i+1
                  except KeyboardInterrupt:
                      print("Exiting program...")
          finally:
              await websocket.send("Le serveur n'est pas connecté à GNURadio")
      	
      
      def start_loop(loop, server):
          loop.run_until_complete(server)
          loop.run_forever()
      
      
      #Lancement Thread UDP 
      udp = Thread(target=listen_udp)			#Création thread pour l'UDP	
      udp.start()
      
      # start a new event loop
      new_loop = asyncio.new_event_loop()
      
      #Lancement Thread WEB 
      port_websockets = 8000		#port pour les connexions websocket	
      nb_clients = 0				#nombre de clients connecté	
      start_server = websockets.serve(listen_ws, "localhost", port_websockets, loop=new_loop)
      web = Thread(target=start_loop, args=(new_loop, start_server))
      web.start()
      print("Serveur websocket à l'écoute sur le port " + str(port_websockets))
      
      for i in range(10):
          print(format(i)+" : " +msg_gnuradio)
          time.sleep(2)
      


      et l'erreur est :

      python3 server_thread.py
      File "server_thread.py", line 19
      global msg_gnuradio
      ^
      IndentationError: unindent does not match any outer indentation level
    4. Contributeur
      @TR_2000Pourquoi supprimer
      msg_gnuradio = "o"
      ?
    5. @yg_beEn tout cas, la ligne 19 est indentée de 4 espaces mais tout le reste l'est d'une tabulation

      on le voit en faisant un copié/collé de ton code

      IndentationError: unindent does not match any outer indentation level
  2. Bonjour,

    IndentationError: la ligne 19 est indentée de 4 espaces mais tout le reste l'est d'une tabulation

    on le voit en faisant un copié/collé de ton code