[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