实现单线程服务器/守护进程(Python)

实现单线程服务器/守护进程(Python),python,sockets,server,daemon,Python,Sockets,Server,Daemon,我正在开发一个服务器(守护进程) 服务器有一个“工作线程”。工作线程运行一个命令队列。当队列为空时,工作线程将暂停(但不会退出,因为它应该在内存中保留某些状态)。为了在内存中有一个状态副本,我需要始终只运行一个(不是几个,也不是零个)工作线程 当客户端连接到Unix套接字并发送命令时,请求将添加到此队列的末尾 发出命令后,将其添加到工作线程的命令队列中。将其添加到队列后,服务器会回复类似“OK”的内容。在服务器接收命令和它的“OK”回复之间应该不会有长时间的停顿。但是,在队列中运行命令可能需要一

我正在开发一个服务器(守护进程)

服务器有一个“工作线程”。工作线程运行一个命令队列。当队列为空时,工作线程将暂停(但不会退出,因为它应该在内存中保留某些状态)。为了在内存中有一个状态副本,我需要始终只运行一个(不是几个,也不是零个)工作线程

当客户端连接到Unix套接字并发送命令时,请求将添加到此队列的末尾

发出命令后,将其添加到工作线程的命令队列中。将其添加到队列后,服务器会回复类似“OK”的内容。在服务器接收命令和它的“OK”回复之间应该不会有长时间的停顿。但是,在队列中运行命令可能需要一些时间

辅助线程的主要“工作”被分成小块(花费相对较少的时间)。在块之间,工作线程检查(“吃”并清空)队列,并根据从队列中提取的数据继续工作


如何在Python中实现这个服务器/守护进程?

这是一个带有internet套接字的示例代码,很容易用unix域套接字替换。它接受您写入套接字的任何内容,将其作为“命令”传递给worker,并在命令排队后立即响应OK。单个工作人员通过睡眠模拟长时间的任务(30)。您可以根据需要对任意多个任务进行排队,立即收到OK,并且每隔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()
导入队列、线程、套接字
从时间上导入睡眠
类工作线程(threading.Thread):
定义初始化(self,q):
超级(工作者,自我)。\uuuu初始化
self.qu=q
def运行(自):
尽管如此:
new_task=self.qu.get(True)
打印新任务
i=0
当我<10时:
打印“工作…”
睡眠(1)
i+=1
尝试:
另一个任务=self.qu.get(False)
打印另一个任务
队列除外。空:
通过
task_queue=queue.queue()
w=工作者(任务队列)
w、 daemon=True
w、 开始()
sock=socket.socket(socket.AF\u INET,socket.sock\u流)
sock.bind(('localhost',4200))
短袜,听(1)
尝试:
尽管如此:
conn,addr=sock.accept()
数据=conn.recv(32)
任务队列.put(数据)
conn.sendall(“确定”)
康涅狄格州关闭
除:
sock.close()

我可以问一下为什么需要单线程吗?如果您有一个线程可以侦听来自套接字的消息并立即向客户端回复“ok”,那么会出现什么问题。然后,在侦听器和工作者之间会有一个队列,侦听器只会将消息分派到此队列。它们将按到达顺序进行处理,工作线程应保留其“内存中的状态”,并且不会被任何其他线程或进程弄乱。@Hannu我坚持我需要单个工作线程。让另一个线程用于套接字侦听是可以的。套接字侦听器线程和队列不应该解决您的问题吗?您的套接字将始终接受新消息,它们将立即得到响应,工作进程将保留其状态,请求将按照到达的顺序进行处理?然后,您的员工可以在认为合适的情况下“吃”队列中的任务。@Hannu感谢您的想法。我会研究它(也许明天)。你能给出更多关于你的想法的细节吗?非常感谢你,但是你的代码似乎不允许工人检查任务中间的队列。(我提醒大家,在我(编辑过的)问题中,工作人员的工作被分成小块,在小块之间检查队列。)还是简单?我还没有仔细阅读它,因为我还有另一份工作,我修改了代码,包括在“工作”时检查队列。get(False)不会阻止队列是否为空,它只会引发queue.empty,这会立即被忽略。经过进一步思考,我得出结论,对于请求,我不应该只打印“OK”,而是首先进行一些快速计算(在回答OK或ERROR之后),这些计算应该在工作线程中(或与工作线程同步),这样它们就不会与工作线程中的另一个操作同时运行,而是按顺序序列化运行。我希望看到修改后的代码(但不要删除您已经编写的代码!)请原谅,您为我做了一些工作,但我希望看到修改后的代码(在不应删除的旧版本代码中)注意,在前面的注释中,我假设响应请求的计算不应在工作线程的当前“小块”完成之前开始