1

私のコードは、複数のソースから 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が停止しますが、キーストロークを送信した場合にのみデータが出力されます。

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

データが送信されるまでスレッドを一時停止する方法はありますか? または、受信したメッセージをシミュレートして、メイン プログラムからデータ バーストをトリガーできますか?

4

1 に答える 1

3

100% の CPU を使用している理由は、書き込むものが何もないときは、書き込むものできるまでできるだけ速く回転し続けるためです。

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

CPU を 100% 使用しないようにするには、待機する何かを見つける必要があります。

あなたの修正は、受信したデータを待つことでこれを行いますが、通常は受信するデータがないため、これはあまり役に立ちません。(あなたが言うように、「キーストロークを送信した場合にのみデータを出力します」。)

その間:

データが送信されるまでスレッドを一時停止する方法はありますか?

もちろん。そして、あなたはすでにそれをやっています。それsendallがそうです。しかし、それは役に立ちません。問題は、すべてのデータを送信すると、送信するデータが増えるまでループを何度も繰り返すことです。

または、受信したメッセージをシミュレートして、メイン プログラムからデータ バーストをトリガーできますか?

もちろん、そのシミュレートされた受信をトリガーするには何を使用しますか? できるだけ速くレシーブをシミュレートしてスピンするだけでは、何の役にも立ちません。

ここで必要なのは、データに関する条件変数だと思います。このようなもの:

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()
于 2013-04-23T23:34:43.707 に答える