簡體   English   中英

python的線程化TCP套接字

[英]threaded TCP sockets with python

我是python編程和套接字的新手,所以我從http://docs.python.org/2/library/socketserver.html處的異步(線程)SocketServer示例開始。

ThreadingMixIn類的示例運行良好,但是對於專家我有兩個問題:

  • 每個新連接都會創建一個新線程,很好。 但是似乎線程永遠不會終止,即使另一側的連接隨着線程數量的增加而關閉。

  • 第二個問題是關於handle方法。 我嘗試從客戶端使用sendall發送2條連續消息,但是第二次發送失敗...看來,實際上handle方法等待第一條消息,然后終止。 我必須添加“ while 1:”才能開始工作。

因此,總而言之,我感到這個示例是無用且不好的,因為它只是創建了一個只能接收一條消息的線程。 如果至少它會自行終止,但對我而言似乎並非如此……

感謝您的投入!

這是服務器的代碼:

import threading
import SocketServer

class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):

    def handle(self):
        data = self.request.recv(1024)
        cur_thread = threading.current_thread()
        response = "{}: {}".format(cur_thread.name, data)
        self.request.sendall(response)

class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    pass


if __name__ == "__main__":

    server = ThreadedTCPServer(('localhost', 13009), ThreadedTCPRequestHandler)

    # Start a thread with the server -- that thread will then start one
    # more thread for each request
    server_thread = threading.Thread(target=server.serve_forever)
    # Exit the server thread when the main thread terminates
    server_thread.daemon = True
    server_thread.start()
    print "Server loop running in thread:", server_thread.name

    raw_input("Hit enter to stop the server")

    server.shutdown()

和客戶的代碼:

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('localhost', 13009))
try:
    sock.sendall('hello\n')
    response = sock.recv(1024)
    print "Received: {}".format(response)

    # A second 'send' will generate an error on Windows.
    # On Mac, no error but the received message is empty as the
    # handle method in the server isn't called for each new message
    sock.sendall('how are you?')
    response = sock.recv(1024)
    print "Received: {}".format(response)

except socket.error, (value,message):
    print "Error: " + message

finally:
    sock.close()

如您所見,每次運行客戶端代碼時,即使先前的套接字已關閉,也會創建一個新線程……或者至少,threading.current_thread()返回一個新的ID。 如何檢查上一個線程是否已停止?

關於@luka的答案; Dietrich是正確的,因為以這種方式使用線程很好。 是的,您只能在給定時間執行一條python指令,但是套接字無論如何通常都是I / O綁定的,所以一切都很好。

知道線程已死亡的最簡單方法不是直接從python中獲取,因為這與您使用的接口有些相似。 相反,我會看一下可以提供此信息的操作系統。 在Linux上,只需執行pstree命令。 您的線程數應顯示為<thread count>*[{process name}] ,其中線程數是您的線程數。

其他方法包括讓您的應用程序打印“狀態線程”,“結束線程”或使用調試的python(pydb)。

關於@luka關於事件驅動的python的最后一點,這是一種過早的優化。 如果您不希望應用程序承受巨大的負擔,請不必擔心。 如果您期望一個巨大的負載,則每個請求的線程派生可能會成為需要解決的瓶頸。

  1. Python是從單線程運行的,因此,如果這是您的目標,那么使用多個線程不會給您帶來任何性能提升。 可能會不必要地花費更多的內存。
  2. 我建議使用gevent庫來抽象並行執行和處理大量套接字。

http://www.gevent.org/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM