2016-09-20 10 views
-1

서버 (데몬)를 개발 중입니다.단일 스레드 서버/데몬 (Python) 구현

서버에는 "작업자 스레드"가 하나 있습니다. 작업자 스레드는 명령 대기열을 실행합니다. 대기열이 비어 있으면 작업자 스레드는 일시 중지됩니다 (메모리의 특정 상태를 보존해야하기 때문에 종료하지 않습니다). 정확히 하나의 상태 복사본을 메모리에 저장하려면 모든 작업자 스레드를 정확하게 실행해야합니다.

클라이언트가 Unix 소켓에 연결하여 명령을 보낼 때이 큐의 끝에 요청이 추가됩니다.

명령이 실행 된 후 작업자 스레드의 명령 대기열에 추가됩니다. 큐에 추가 된 후 서버는 "OK"와 같은 응답을 보냅니다. 서버가 명령을 수신하고 "OK"응답을 보내는 사이에 긴 정지가 없어야합니다. 그러나 대기열에서 명령을 실행하는 데는 약간의 시간이 걸릴 수 있습니다.

작업자 스레드의 주요 "작업"은 작은 (비교적 적은 시간 소요) 청크로 분할됩니다. 청크 사이에서 작업자 스레드는 큐를 검사 ("먹고"비 웁니다)하고 큐에서 추출 된 데이터를 기반으로 작업을 계속합니다.

이 서버/데몬을 Python으로 구현하는 방법은 무엇입니까?

+0

왜 내가 단일 스레드 일 필요가 있는지 물어볼 수 있습니까? 소켓에서 메시지를 수신하고 클라이언트에 즉시 "ok"로 응답하는 스레드가 있다면 무엇이 고장 났을 것입니다. 그런 다음 청취자와 작업자 사이에 대기열이 있으며 청취자는 메시지를이 대기열로 발송합니다. 그들은 도착 순서대로 처리되고 작업자 스레드는 "메모리의 상태"가 유지되어야하며 다른 스레드 또는 프로세스에 의해 엉켜 없어야합니다. – Hannu

+0

@Hannu 싱글 ** worker ** 스레드가 필요하다고 주장합니다. 소켓 리스닝을위한 또 다른 스레드를 갖는 것은 괜찮습니다. – porton

+2

소켓 리스너 스레드와 큐가 문제를 해결하면 안됩니까? 소켓은 항상 새 메시지를받습니다. 즉, 즉시 응답하고 작업자는 상태를 보존하며 요청은 도착한 순서대로 처리됩니다. 그런 다음 작업자는 대기열에서 작업을 "먹을"수 있습니다. – Hannu

답변

1

이것은 인터넷 소켓이있는 샘플 코드이며, 유닉스 도메인 소켓으로 쉽게 대체됩니다. 소켓에 쓰는 모든 것을 가져 와서 "명령"으로 worker에 전달하고, 명령을 대기시키는 즉시 확인에 응답합니다. 한 명의 작업자는 sleep (30)이라는 긴 작업을 시뮬레이션합니다. 원하는만큼 많은 작업을 대기열에 넣고 즉시 30 초마다 OK를 받으면 작업자가 대기열에서 명령을 인쇄합니다.

import Queue, threading, socket 
from time import sleep 

class worker(threading.Thread): 
    def __init__(self,q): 
     super(worker,self).__init__() 
     self.qu = q 

    def run(self): 
     while True: 
      new_task=self.qu.get(True) 
      print new_task 
      i=0 
      while i < 10: 
       print "working ..." 
       sleep(1) 
       i += 1 
       try: 
        another_task=self.qu.get(False) 
        print another_task 
       except Queue.Empty: 
        pass   

task_queue = Queue.Queue() 
w = worker(task_queue) 
w.daemon = True 
w.start() 

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
sock.bind(('localhost', 4200)) 
sock.listen(1) 
try: 
    while True: 
     conn, addr = sock.accept() 
     data = conn.recv(32) 
     task_queue.put(data) 
     conn.sendall("OK") 
     conn.close() 
except: 
    sock.close() 
+0

대단히 고마워요.하지만 코드는 작업자가 작업 중간에 큐를 검사하는 것을 허용하지 않는 것 같습니다. (나는 (편집 된) 질문에서 작업자의 작업이 대기열을 검사하는 작은 덩어리로 나뉘어 있음을 상기시킨다.) – porton

+0

아니면 쉬울 까? 나는 또 다른 직업을 가지고 있기 때문에 아직 그것을 아주 조심스럽게 읽지 못했습니다. – porton

+1

"작업 중"대기열 검사를 포함하도록 코드를 수정했습니다. queue가 비어 있으면 get (False)가 차단되지 않고 Queue.Empty가 발생하고 즉시 무시됩니다. – Hannu