2016-09-20 105 views
-1

我正在開發一個服務器(守護進程)。實現單線程服務器/守護進程(Python)

服務器有一個「工作者線程」。工作線程運行一系列命令。當隊列爲空時,工作線程暫停(但不會退出,因爲它應該保留內存中的某個狀態)。要在內存中擁有完全一個狀態的副本,我需要全部運行一個(不是幾個而不是零)工作線程。

當客戶端連接到Unix套接字併發送命令時,將請求添加到此隊列的末尾。

命令發出後,它被添加到工作線程的命令隊列中。將它添加到隊列後,服務器回覆「OK」之類的內容。服務器接收命令和「確定」回覆之間應該沒有很長的停頓時間。但是,在隊列中運行命令可能需要一些時間。

工作者線程的主要「工作」被拆分成小塊(佔用相對較少的時間)塊。在塊之間,工作線程檢查(「吃」和清空)隊列,並根據從隊列中提取的數據繼續工作。

如何在Python中實現這個服務器/守護進程?

+0

請問爲什麼它需要成爲單線程? 如果您有一個線程可以偵聽來自套接字的消息並立即向客戶端回覆「ok」,那麼會發生什麼情況?然後您將在偵聽器和worker之間有一個隊列,並且偵聽器只會將消息發送到該隊列。它們將按照到達順序進行處理,並且工作線程應該保留其「內存中的狀態」並且不會被任何其他線程或進程混淆。 – Hannu

+0

@Hannu我堅持我需要單**工**線程。爲了讓套接字偵聽有另一個線程是可以的。 – porton

+2

套接字偵聽器線程和隊列不應該解決您的問題嗎? 你的套接字總是會接受新的消息,他們會立即作出迴應,工作人員會保存它的狀態,並按照他們到達的順序處理請求?您的工作人員可以根據需要從隊列中「吃」任務。 – Hannu

回答

1

這是一個帶互聯網套接字的示例代碼,很容易替換爲unix域套接字。它將任何你寫入套接字的東西,作爲一個「命令」傳遞給工作者,只要它已經排隊命令就回應OK。單身工作人員用睡眠模擬冗長的任務(30)。您可以根據需要排列儘可能多的任務,並且每30秒鐘立即接收一次,您的工作人員會從隊列中輸出一條命令。

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

我修改了代碼,在「工作」的同時包括檢查隊列。如果隊列爲空,get(False)不會阻塞,只會引發Queue.Empty,這會立即被忽略。 – Hannu