我的代码接受来自多个源的gps数据聚合它并将其发送回连接到线程单个套接字的多个客户端。我得到了它的工作,但输出线程似乎用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 stop,但只有在我发送击键时它才会输出数据。
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
有没有办法在发送数据之前暂停线程?或者我可以模拟收到的消息来触发主程序的数据突发吗?
答案 0 :(得分:3)
它使用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()