multithreading - Is this python code thread safe (thread with twisted)? -


i writing application collect udp messages , process them every 1sec.

application prototype looks like:

from twisted.internet.protocol import datagramprotocol twisted.internet import reactor import threading import time class udplistener(datagramprotocol): messages = [] def datagramreceived(self, data, (host, port)): self.messages.append(data) class messenger(threading.thread): listener = none def __init__(self): threading.thread.__init__(self) def run(self): while true: time.sleep(1) recivedmessages = self.listener.messages length = len(recivedmessages) messagestoproccess = recivedmessages[0:length] #dosomethingwithmessages(messagestoproccess) del self.listener.messages[0:length] print(length) listener = udplistener() messenger = messenger() messenger.listener = listener messenger.start() reactor.listenudp(5556, listener) reactor.run() 

i not sure if can remove beginning values list (del self.listener.messages[0:length]) without risk incoming message changes list , application crashes.

update - version lock

class messenger(threading.thread): listener = none lock = threading.lock() def __init__(self): threading.thread.__init__(self) def run(self): while true: time.sleep(1) recivedmessages = self.listener.messages self.lock.acquire() try: length = len(recivedmessages) messagestoproccess = recivedmessages[0:length] del self.listener.messages[0:length] except exception e: raise e finally: self.lock.release() #dosomethingwithmessages(messagestoproccess) print(length) 

your code isn't thread-safe, no. you'd need have lock around messages.

however, don't need thread here. why not this?

from twisted.internet.protocol import datagramprotocol twisted.internet import reactor class udplistener(datagramprotocol): callinglater = false messages = [] def process(self): dosomethingwithmessages(self.messages) self.messages = [] self.callinglater = false def datagramreceived(self, data, (host, port)): self.messages.append(data) if not self.callinglater: reactor.calllater(1.0, self.process) self.callinglater = true listener = udplistener() reactor.listenudp(5556, listener) reactor.run() 

update: here how original version work lock, educational purposes only. note not efficient , more prone bugs. edit: separated message logic out udplistener classes using don't need know gooey internal details.

from twisted.internet.protocol import datagramprotocol twisted.internet import reactor import threading import time class udplistener(datagramprotocol): message_lock = threading.lock() messages = [] def datagramreceived(self, data, (host, port)): self.message_lock: self.messages.append(data) def getandclearmessages(self): self.message_lock: res = self.messages self.messages = [] return res class messenger(threading.thread): listener = none def __init__(self): threading.thread.__init__(self) def run(self): while true: time.sleep(1) recivedmessages = self.listener.getandclearmessages() length = len(recivedmessages) #dosomethingwithmessages(recivedmessages) print(length) listener = udplistener() messenger = messenger() messenger.listener = listener messenger.start() reactor.listenudp(5556, listener) reactor.run() 

Comments

Popular posts from this blog

javascript - backbone.js Collection.add() doesn't `construct` (`initialize`) an object -

php - Get uncommon values from two or more arrays -

Adding duplicate array rows in Php -