2013-03-11 1 views
0

파이썬 스레드를 사용하여 웹 사이트 IP 주소를 확인하고 있습니다. 이것은 해결을위한 내 작업자 프로세스입니다. 이것은 데몬 스레드입니다.파이썬 스레드가 컴퓨터를 고정시키고있는 것 같습니다.

def get_ip_worker(): 
    """This is the worker (thread) process for parsing ips, this process takes domain from the q processes it 
    and then saves it to another q""" 

    socket.setdefaulttimeout(3) 
    while True: 
     domain = domains_q.get() 
     try: 
      addr_info = socket.getaddrinfo(domain, 80, 0, 0, socket.SOL_TCP) 
      for family, socktype, proto, name, ip in addr_info: 
       if family == 2: #okay it's ipv4 
        ip, port = ip 
        processed_q.put((ip, domain)) 
       elif family == 10: #okay it's ipv6 
        ip, port, no_1, no_2 = ip 
        processed_q.put((ip, domain)) 
     except: 
      pass 
      #print 'Socket Error' 

     domains_q.task_done() 

EDIT : 도메인 domains_q.get =() 블록 아이템까지이 줄 대기열 가능하다.

이 문제는 300 스레드에서 실행하면로드 평균은 괜찮은 것처럼 보이지만 간단한 ls -la는 5 초가 걸리고 모든 것이 느립니다. 나는 어디로 잘못 갔는가? 비동기 또는 다중 처리를 사용해야합니까?

+0

빈 큐 예외가 루프를 깨뜨리는 것이 확실합니까? – andsoa

+0

domains_q.get()이 행은 항목을 사용할 수있을 때까지 차단됩니다. 게시물에 추가했습니다. – nacholibre

답변

0

300 개의 연결을 병렬로 300 개의 연결을 처리해야합니까? 나는 많은 스레드를 생성 해 본 적이 없지만 문제가 될 수 있습니다. 그리고 그것은 분명히 문제를 푸는 좋은 방법이 아닙니다. 일반적으로 다른 옵션이 있습니다. 첫째, 300 개의 연결을 수신하는 데 300 개의 스레드가 필요하지 않습니다. HW 및 OS에서 작동하는 스레드 수를 만듭니다. 단일 스레드를 사용하여 주 대기열에서 요청을 검색 한 다음 thread pool에서 스레드로 전달하십시오.

현재 "대기열에서 검색"작업이 실제로 차단되고 대기열이 비어 있는지 확인하십시오. 그렇지 않은 경우 들어오는 요청의 유무에 의존하지 않고 루프가 항상 실행될 수 있습니다.

정말로 필요한 것은 소켓을위한 non-blocking 모드와 소켓 중 하나가 읽거나 쓸 준비가 될 때까지 기다리는 것입니다. select.select(). 이 코드는 독자적으로 작성할 수 있습니다. 열망하지 않으려면 gevent (또는 twisted)과 같은 좋은 비동기 네트워킹 라이브러리가 프로그램 아키텍처를 개선하는 데 도움이 될 수 있습니다. 멀티 코어 CPU의 모든 기능을 활용하는 것은 별개의 질문이지만 적어도 적어도 gevent (여러 프로세스를 실행하는 gunicorn을 기반으로하며 시도한 적은 없지만)에 대한 해결책이 있다고 들었습니다. 그러나 실행 속도가 아닌 문제를 겪고 있다고 생각합니다. 그러나 한 번에 여러 개체에서 I/O를 효과적으로 기다릴 필요가 있습니다. 그렇다면 스레드를 방대한 용도로 사용하지 말고 파이썬에서뿐만 아니라 다중 스레드 프로그래밍에 더 적합한 GIL이없는 언어에서도 효과적입니다. multiprocessing은 GIL을 피하지만 자체 실행 비용을 추가하므로 여기서 사용하지 않을 것을 제안합니다.

관련 문제