2013-04-23 31 views
0

我的代碼接受來自多個源的gps數據將其聚合並將其發送回連接到單個線程套接字的多個客戶端。我得到它的工作,但輸出線程似乎與cpu資源跑。Python socketserver將數據發送到多個客戶端cpu使用高

如果我添加代碼以等待來自客戶端的一些數據,那麼cpu使用消失,但客戶端只接受gps信息流,他們不發送任何東西。

下面是發送數據不錯,但運行高CPU

class ThreadedServerRequestHandler(SocketServer.StreamRequestHandler): 

    def handle(self): 
     global SendData 
     global SendNow 
     while True: 
      SendNow 
      for line in SendData: 
       self.request.sendall(line) 
       SendData = [] 
       SendNow = False 
     return 

class ServerThread(SocketServer.ThreadingMixIn, SocketServer.TCPServer): 
    daemon_threads = True 
    allow_reuse_address = True 

if __name__ == '__main__': 
    import socket 
    import threading 

    address = TxServer 
    server = ServerThread(address, ThreadedServerRequestHandler) 

    t = threading.Thread(target=server.serve_forever) 
    t.setDaemon(True) # don't hang on exit 
    t.start() 

,如果我將其更改爲以下CPU停止工作,但如果我發送一個按鍵它只輸出數據的服務器代碼。

class ThreadedServerRequestHandler(SocketServer.StreamRequestHandler): 

    def handle(self): 
     global SendData 
     global SendNow 
     while True: 
      self.data = self.request.recv(1024).strip() 
      if self.data == '': 
       print 'closing thread'    
       break 
      while SendNow == True: 
       for line in SendData: 
        self.request.sendall(line) 
       SendData = [] 
       SendNow = False 
     return 

有什麼辦法來暫停線程,直到數據被髮送?或者我可以模擬收到的消息觸發主程序的數據突發?

回答

2

它使用100%的CPU的原因是,當你有什麼可寫的,你只是保持一樣快,您可以直到東西寫紡:

while True: 
    SendNow 
    for line in SendData: 
     self.request.sendall(line) 
     SendData = [] 
     SendNow = False 

爲了使它不使用100%的CPU,你必須找到一些東西讓它等待。

您的修補程序通過等待收到的數據來做到這一點,但由於您通常沒有任何數據可以接收,所以這不是很有用。 (正如你所說的那樣,「它只有當我送一個按鍵輸出數據」。)

同時:

有什麼辦法暫停線程,直到數據被髮送?

當然。你已經在做。這就是sendall所做的。但是這並沒有幫助。問題是,一旦你發送了所有的數據,你會一遍又一遍地循環,直到有更多的數據要發送。

或者我可以模擬收到的消息觸發主程序的數據突發?

當然,但你會用什麼來觸發模擬接收?如果你只是儘可能快地模擬接收,那對什麼都沒有幫助。

我想這裏你想要的是圍繞數據的condition variable。事情是這樣的:

SendCondition = threading.Condition() 

class ThreadedServerRequestHandler(SocketServer.StreamRequestHandler): 

    def handle(self): 
     global SendCondition 
     global SendData 
     while True: 
      with SendCondition: 
       while not SendData: 
        SendCondition.wait() 
       for line in SendData: 
        self.request.sendall(line) 
       SendData = [] 

然後,無論你的代碼是設置SendData(你沒有顯示)看起來是這樣的:

global SendCondition 
global SendData 
# ... 
new_send_data = <whatever> 
with SendCondition: 
    SendData.append(new_send_data) 
    SendCondition.notify() 
+1

輝煌,就像一個魅力。這是Google編程時遇到的問題,我不知道我不知道什麼,所以我的搜索問題受到我已經瞭解的內容的限制。 – user2304910 2013-04-24 08:55:58

+1

@ user2304910:這就是爲什麼它值得通過一個教程,而不是隻抓取示例代碼,並試圖找出它。問題在於,對於你想要做的事情,經常沒有任何好的教程。而且,如果有的話,他們很難找到。(我確信有人寫了一篇很好的「Python中的線程之間安全地共享數據的不同方式介紹」,但我不知道在哪裏找到它......) – abarnert 2013-04-24 17:55:08

相關問題