[PIPython] Conferma sull'utilizzo di socket e thread
Gianmario Salvetti
salvetti.gianmario
Ven 19 Nov 2004 15:16:54 CET
Salve a tutti mi servirebbe una conferma sul mio operato. Sto
realizzando un' applicazione client-server multi thread. Ho realizzato
un oggetto Server, che eredita la classe threading.Thread ed implementa
un metodo __init__, un metodo run (come le classi discendenti di Thread
devono fare) ed un metodo stop. Nel corpo del metodo run come potete
vedere c'e' un ciclo while sulla variabile NO_STOP. Il metodo stop,
rende NO_STOP False e pertanto permette al thread di uscire dal ciclo
while. Poiche' stop viene chiamato da un thread diverso da quello che
opera nel metodo run, la variabile NO_STOP e' una variabile contesa e
pertanto ho provveduto ad utilizzare dei monitor (variabili di tipo
Condition in python) per sincronizzare l'accesso ad essa. Impostare la
variabile NO_STOP, non e' sufficiente per fare uscire il thread dal
ciclo while, infatti potrebbe essere in attesa di una connessione (conn,
addr = self.sck.accept()). Ho risolto richiamando il metodo shutdown
dell oggetto self.sck dalla fuzione stop (self.sck.shutdown(0)) e tutto
sembra funzionare correttamente, ma a questo punto mi chiedo: e'
corretta questa ultima operazione (dal punto di vista formale), visto
che accedo ad una variabile condivisa senza nessuna forma di
sicronizzazione?. Oppure gli oggetti di tipo Socket implementano nei
loro metodi qualche forma di sincronizzazione? (tipo:
class Socket:
....
def shutdown(a):
monitor.acquire()
........
monitor.release()
....
). Grazie
class Server(threading.Thread):
"""Questo oggetto si occupa di gestire delle connessioni. Una volta
accettata una connessione identifica il
tipo di servizio richiesto, crea un nuvo thread al quale passa la
connessione per la successiva gestione.
Il thread viene poi memorizzato in una lista che periodicamente
viene ripulita dai thread morti. Infine,
quando viene chiamato il metodo stop, questo oggetto prima di
terminare aspetta che i suoi thread figli
terminino."""
def __init__(self, IP, PORT, f):
threading.Thread.__init__(self)
self.IP = IP
self.PORT = PORT
self.NO_STOP = True
self.monitor = threading.Condition()
self.f = f
def __remove_childs_died(self, threadChilds):
result = []
for threadChild in threadChilds:
if threadChild.isAlive():
result.append(threadChild)
return result
def run(self):
self.sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sck.bind((self.IP, self.PORT))
self.sck.listen(1)
threadChilds = []
self.monitor.acquire()
NO_STOP = self.NO_STOP
self.monitor.release()
conn = None
while NO_STOP:
try:
conn, addr = self.sck.accept()
except socket.error:
self.monitor.acquire()
NO_STOP = self.NO_STOP
self.monitor.release()
else:
threadChild = threading.Thread(target=self.f,
args=(conn,addr))
threadChild.start()
threadChilds.append(threadChild)
threadChilds = self.__remove_childs_died(threadChilds)
for threadChild in threadChilds:
threadChild.join()
def stop(self):
self.monitor.acquire()
self.NO_STOP = False # Imposto la variabile per uscire dal ciclo
self.sck.listen(0) # Non accetto piu connessioni
self.sck.shutdown(0) # Tronco un eventuale tentativo di connessione
self.monitor.release()
p.s.
In questa ML e' permesso spedire il codice in formato html (in modo da
poter utilizzare
la sintassi colorata) ?
Gianmario.
More information about the Python
mailing list