Hello.
I'm using the asyncore and _chat modules to create a network server. I
also have, running in a separate thread(s), a "producer" which needs to
"push" data onto the network connection(s). (This is all for a
multi-player game server, so the threads would be individual games,
that need to update the players when new events happen in the game)
I currently have a module level list of async_chat instances, which the
thread then reads and uses the 'push' method of async_chat.
I've done some very quick tests, but wanted to know more formally if
the async_chat.push() method is thread safe?
ie. can i be sure that the data that the thread pushes onto the
connection will always be complete, and never "over-written" by another
thread?
Here is an example, which creates a whack of threads, which push their
message down the first connection made to the server. I just use a
telnet client to test it. I haven't seen any over-writing of values,
but this is a very basic test/example of what i'm doing. I just want to
make sure that this _is_ ok, or if i should be using a Queue...
<file>
import asynchat
import asyncore
import socket
from threading import Thread
import time
import random
clients = []
class pulse_thread(Thread):
def __init__(self, string):
Thread.__init__(self)
self.msg = string
def run(self):
while True:
time.sleep(random.random())
if(len(clients)):
clients[0].push(self.msg)
class Chat(asynchat.async_chat):
def __init__(self, sock, addr, terminator="\r\n", name="me"):
asynchat.async_chat.__init__(self, conn=sock)
self.rmq = []
self.terminator = terminator
self.set_terminator(self.terminator)
# push self onto module client list, so threads can access me
clients.append(self)
def collect_incoming_data(self, data):
"""Buffer the data"""
self.rmq.append(data)
def found_terminator(self):
print "".join(self.rmq)
self.rmq = []
class cServer(asyncore.dispatcher):
# constructor method
def __init__(self, addr, terminator="\r\n"):
# initalize asyncore
asyncore.dispatcher.__init__(self)
self.terminator = terminator
# create a socket to listen on
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
# bind the socket to the ip/port
self.bind(addr)
# listen ??? don't know about the 5 ????
self.listen(50)
# EVENT handle_accept - fired when server accepts an new connection
def handle_accept (self):
# fire the accept method > returns a connection object
conn, addr = self.accept()
# extend the connection with cSock Class (another asyncore)
#cSock(conn, addr)
Chat(conn,addr,self.terminator)
if __name__ == '__main__':
for i in range(1,99):
x = pulse_thread(":%02d:\n\r" % (i,))
x.start()
myserver = cServer(('127.0.0.1',7000))
asyncore.loop()
</file>
Please let me know if this is totally the _wrong_ way to do it!
Thanks,
Jos