2014-09-05 1 views
0

저는 파이썬 프로그래밍과 소켓에서 새롭기 때문에 비동기 (쓰레딩) SocketServer 예제를 http://docs.python.org/2/library/socketserver.html에서 시작했습니다.파이썬을 가진 쓰레드 된 TCP 소켓

  • 각각의 새로운 연결이 잘, 새 스레드를 생성합니다

    ThreadingMixIn 클래스의 예 그러나 나는 전문가를위한 2 개 질문이, 잘 작동합니다. 그러나 스레드 번호가 증가함에 따라 상대방의 연결이 닫히더라도 스레드가 종료되지 않는 것처럼 보입니다.

  • 두 번째 질문은 핸들 방법에 대한 것입니다. 내 클라이언트에서 sendall 함께 2 연속 된 메시지를 보내려고했지만 두 번째 보내기 실패합니다 ... 그것은 실제로 첫 번째 메시지를 기다린 후 처리 메서드를 나타납니다. 나는 일하기 위해 '1 : while'을 추가해야했다.

결론적으로,이 예제는 단지 하나의 메시지 만 수신 할 수있는 스레드를 생성하므로이 예제가 쓸모없고 좋지 않다는 느낌이 들었습니다. 적어도 그것이 그 자체로 종료 될 것이지만 그것은 나를위한 경우 인 것처럼 보입니다 ...

당신의 의견을 보내 주셔서 감사합니다! 당신이 볼 수 있듯이, 때마다 클라이언트의 코드를 실행, 새로운 스레드는 생각도 만들어

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() 

:

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() 

그리고 클라이언트의 코드 : 여기

은 서버에 대한 코드입니다 이전 소켓이 닫혔거나 적어도 threading.current_thread()는 새 ID를 반환합니다. 이전 스레드가 중지되었는지 어떻게 확인할 수 있습니까?

+0

작성한 코드를 포함 할 수 있습니까? – dano

답변

0
  1. 파이썬은 단일 스레드에서 실행되므로 다중 스레드를 사용한다고해도 이것이 목표라면 성능이 향상되지 않습니다. 그것은 아마도 더 많은 기억을 낭비 할 필요가 없을 것입니다.
  2. gevent 라이브러리를 사용하여 병렬 실행을 추상화하고 많은 수의 소켓을 처리하는 것이 좋습니다.

@의 루카의 대답에 관해서 http://www.gevent.org/

+1

파이썬은 여러 스레드에서 실행할 수 있지만 GIL은 한 번에 하나의 스레드 만 파이썬 코드를 실행하도록합니다. 다른 스레드는 시스템 호출이나 장기 실행 외국 함수를 실행할 수 있습니다. –

+0

이벤트 루프를 실행하는 것보다 우수합니다 (단일 처리 됨) –

+0

스레드를 사용하는 경우 IO 루프는 이벤트 루프를 사용할 때보 다 훨씬 간단합니다. 그래서 예, 그것은 훨씬 더 좋을 수 있습니다. 그러나 응용 프로그램에 따라 다릅니다. –

1

; Dietrich는 스레드를이 방법으로 사용하는 것이 좋습니다. 네, 주어진 시간에 오직 하나의 파이썬 명령어 만 실행할 수 있습니다.하지만 소켓은 일반적으로 I/O 바인딩되어 있으므로 모든 것이 좋습니다.

쓰레드가 죽었 음을 알 수있는 가장 쉬운 방법은 사용하고있는 인터페이스로 다소 추상화 되었기 때문에 파이썬에서 직접 죽은 것이 아닙니다. 대신이 정보를 제공 할 수있는 운영 체제를 살펴 보겠습니다. Linux에서는 pstree 명령을 실행하기 만하면됩니다. 스레드 수는 <thread count>*[{process name}]과 같이 표시되어야합니다. 여기서 스레드 수는 스레드 수입니다.

다른 방법으로 응용 프로그램에서 "stating thread", "ending thread"또는 python debugged (pydb)를 사용하여 인쇄하는 방법이 있습니다.

이벤트 주도형 파이썬에 관해서 @luka에 의해 제기 된 마지막 점에 관해서는 일찍이 일종의 최적화입니다. 응용 프로그램에 큰 부담을주지 않으려는 경우 걱정하지 마십시오.거대한 부하가 예상되는 경우 요청 당 스레드를 포킹하는 경우 이 될 수있는 병목 현상이 될 수 있습니다.