Python 从多人聊天室开始谈系列 - 线程同步与读者写者模型
接下来,我们不可避免的会遇到线程同步问题,这是因为我们涉及到了共享数据的问题(也就是一个数组)。
我们来看看Python的锁:
threadLock = threading.Lock()
在同步的地方,用:
threadLock.acquire()
lists.append(receiver)
threadLock.release()
进行锁的增加和释放。
锁是一种非常简单的工具,但锁的使用决定了你多线程的运行效率。
因此,我们在此介绍一种模型:读者写者模型,来解决效率的问题。
读者写者模型,简单的来说就是:有读者的时候不允许写入。
模型的概念可以看这里:http://c.biancheng.net/cpp/html/2601.html
这里我们写成Python版就行了:
class scanThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
while True:
c, addr = s.accept()
receiver = receiveThread(c, addr)
receiver.setDaemon(True)
threadLock.acquire()
lists.append(receiver)
threadLock.release()
receiver.start()
print lists
print 'Got connection from', addr
# c.send('Thank you for connecting')
class receiveThread(threading.Thread):
counter = 0
def __init__(self, client, address):
threading.Thread.__init__(self)
self.client = client
self.address = address
def run(self):
while True:
try:
msg = eval(recv_msg(self.client))
except:
break
if msg:
print msg
if msg['type'] == 'message':
mutex.acquire()
if receiveThread.counter == 0:
threadLock.acquire()
receiveThread.counter += 1
mutex.release()
for receiver in lists:
if receiver.address != self.address:
print self.address, ' -> ', receiver.address
try:
send_msg(receiver.client, repr(msg).encode('utf8'))
except Exception, e:
lists.remove(receiver)
mutex.acquire()
receiveThread.counter -= 1
if receiveThread.counter == 0:
threadLock.release()
mutex.release()
elif msg['type'] == 'command':
if msg['content'] == 'quit':
threadLock.acquire()
lists.remove(self)
threadLock.release()
break
完整的代码如上。
这里有一部分如send_msg
函数是为了解决下一篇我们要说的TCP传输问题所封装的函数,而encode则是为了解决中文传输乱码的问题。
植入部分
如果您觉得文章不错,可以通过赞助支持我。
如果您不希望打赏,也可以通过关闭广告屏蔽插件的形式帮助网站运作。