Bonjour,
toujours mes problèmes de threads
j'ai bien compris par ailleurs au vu de mes différents post qu'on peut pas les arrêter "brutalement"
et donc qu'il est souhaitable de leur coller une variable pour les arrêter dans ce style
toutefois la je rencontre un problème étonnant avec un serveur Modbus dans un thread
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 class StoppableThread(threading.Thread): """Thread class with a stop() method. The thread itself has to check regularly for the stopped() condition.""" def __init__(self): threading.Thread.__init__(self) self._stopper = threading.Event() def stopit(self): self._stopper.set() def stopped(self): return self._stopper.is_set() def run(self): while True: if self.stopped(): return time.sleep(1)
voici le code de mon serveur
j'utilise QModMaster comme client
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78 import threading import logging from socketserver import TCPServer,ThreadingMixIn from collections import defaultdict from umodbus import conf from umodbus.server.tcp import RequestHandler, get_server from umodbus.utils import log_to_stream from utils.AppUtilities import StoppableThread, Utilities class ThreadingServer(ThreadingMixIn, TCPServer): pass class ModbusServer(StoppableThread): ''' Classe permettant la détection et le tracking des camions et voitures. ''' def __init__(self, active = True, Host = 'localhost', Port = '5020'): ''' Constructor ''' StoppableThread.__init__(self) log_to_stream(level = logging.DEBUG) self.__mutex = threading.Lock() self.active = active # A very simple data store which maps addresss against their values. self.__data_store = defaultdict(int) # Enable values to be signed (default is False). conf.SIGNED_VALUES = False if self.active: TCPServer.allow_reuse_address = True self.app = get_server(ThreadingServer, (Host, Port), RequestHandler) @self.app.route(slave_ids = [1], function_codes = [3, 4], addresses = list(range(0, 100))) def read_data_store(slave_id, function_code, address): """" Return value of address. """ return self.__data_store[address] @self.app.route(slave_ids = [1], function_codes = [6, 16], addresses = list(range(0, 100))) def write_data_store(slave_id, function_code, address, value): """" Set value for address. """ with self.__mutex: self.__data_store[address] = value print(self.__data_store) def setData(self,address,value): if self.active: with self.__mutex: self.__data_store[address] = value def getData(self,address): if self.active: with self.__mutex : return self.__data_store[address] def setDataStore(self,value): if self.active: with self.__mutex: self.__data_store = value def getDataStore(self): if self.active: with self.__mutex : return self.__data_store def stop(self): self.app.shutdown() self.app.server_close() def run(self): try: self.app.serve_forever() finally: self.app.shutdown() self.app.server_close()
bref celui ci se comporte comme un serveur TCP classique
c'est a dire qu'il doit avoir un accept puis a crée deux threads par client (réception et émission)
donc quand on fait un shutdown et un close ben les threads clients ne sont pas fermés et donc le programme ne s'arrête pas... évidement si le client se déconnecte ca marche
voici le code de test de que j'ai fait
je me doute que le passage en processus pourrait peut être marcher toutefois les fonction getData et setData serait pas forcement accessible facilement...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 def testModbusServer(boucle = True): print("- TEST MODEBUS ----------------------------------------------") ModbusThread = ModbusServer(True, "10.7.58.212", 5020) ModbusThread.start() # print("> pause") time.sleep(15) # print("> fin pause") ModbusThread.app.shutdown() ModbusThread.app.server_close() # print("> verification thread") while boucle: nbThreadRunning = 0 for t in threading.enumerate(): if t.is_alive(): print(f"thread en cours = {t.getName()}") nbThreadRunning += 1 if t.name.startswith("Thread"): cc = 0 pass # arret si il reste seulement MainThread if nbThreadRunning <= 1: break; time.sleep(1) pass #-------------------------------------------------------------------------------- # Main #-------------------------------------------------------------------------------- if __name__ == '__main__': print("--------------------------------------------------------------") print(f" Test ") print("--------------------------------------------------------------") testModbusServer() print("-voila la veritable fin---------------------------------------")
bref est ce que quelqu'un aurait une solution pour que lorsque que l'on shutdown ou close le serveur celui ci ferme toutes les socket qu'il a ouvert et ferme proprement ses threads
merci
Partager