2013-04-23 28 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

相关问题