本文研究的主要是Python編程scoketServer實現多線程同步的相關內容,具體介紹如下。
開發過程中,為了實現不同的客戶端同一時刻只能有一個使用共同數據。
雖說用Python編寫簡單的網絡程序很方便,但復雜一點的網絡程序還是用現成的框架比較好。這樣就可以專心事務邏輯,而不是套接字的各種細節。SocketServer模塊簡化了編寫網絡服務程序的任務。同時SocketServer模塊也是Python標準庫中很多服務器框架的基礎。
網絡服務類:
SocketServer提供了4個基本的服務類:
TCPServer針對TCP套接字流
UDPServer針對UDP數據報套接字
UnixStreamServer和UnixDatagramServer針對UNIX域套接字,不常用。
首先,明確一點,在scoketServer中,每當有一個客戶端連接成功后都會為每個客戶端創建一個線程。
為了讓這些多線程之間能夠同步執行,我的做法是:再創建一個線程類,這個線程類中做一些我的項目需要做的事情,,當某個客戶端想成使用到這個線程時,給當前線程加鎖,運行完成后釋放鎖。
請指教
詳細步驟請看注釋:
#coding=gbk__author__ = 'kaikai'import Queueimport threadingimport timeimport SocketServer#全局線程鎖threadLock = threading.Lock()#全局數據隊列data = Queue.Queue()#工作線程類,class testThead(threading.Thread): global data def __init__(self): threading.Thread.__init__(self) def begin_test(self): self.start() def run(self): global threadLock threadLock.acquire() # 從隊列中取出連接和數據 if data.qsize()>0: this_receive = data.get() else: print "data size is empty !" return # 解析數據,獲得連接和數據 # 使用當前數據的conn this_conn = this_receive.keys()[0] this_data = this_receive[this_conn] # 釋放鎖 threadLock.release() def send_msg(self,conn,msg): try: conn.sendall(msg) except Exception as e: print "send " + str(msg) +"fail !!!!!!!!!!!!!!" def recv_msg(self,conn): try: recv_msg = conn.recv(2048) return recv_msg except Exception as e: print " recv msg fail !!!!!!!!!!" return None# 每有一個客戶端生成一個線程。所有線程調用同一個測試線程,如果測試線程在鎖定中,則進入等待。class MyServer(SocketServer.BaseRequestHandler): def send_msg(self,conn,msg): try: conn.sendall(msg) except Exception as e: print "send " + str(msg) +"fail !!!!!!!!!!!!!!" def recv_msg(self,conn): try: recv_msg = conn.recv(2048) return recv_msg except Exception as e: print " recv msg fail !!!!!!!!!!" def handle(self): global data # 獲得連接 conn = self.request print "client connect!" # 循環接受客戶端數據 while True: # 接受客戶端發送過來的參數 receive_data = self.recv_msg(conn) print receive_data # 如果參數為空,返回報錯 結束循環 if not receive_data: print "can not get data form client ! " break print "data size put before: " + str(data.qsize()) # 將連接和數據添加到隊列中 放入連接可以保證在另一個線程中直接使用連接給相應客戶端發送或者接受數據。同時保證數據與客戶端的一一對應 data.put({conn:receive_data}) print "data size put aftter: " + str(data.qsize()) # 初始化測試線程 testThead_this = testThead() # 開始測試線程 testThead_this.begin_test() # testThead_this.start() # 等待測試線程執行結束 testThead_this.join() print "this test end "if __name__ == "__main__" : try: server = SocketServer.ThreadingTCPServer(('192.168.100.100',56780),MyServer) server.timeout = 100 print "Server run success !!!! " server.serve_forever() except Exception as e: print "Server run failed !!!!/n error: " + str(e)
新聞熱點
疑難解答