2016-09-20 106 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