从定时器线程终止进程

0 投票
1 回答
1213 浏览
提问于 2025-04-18 02:35

我先从代码开始说起。

from multiprocessing import Process, Event, Queue
from threading import Timer
from Queue import Empty

class MyServer(Process):
    def __init__(self, port, queue):
        Process.__init__(self)

        self.port = port
        self.queue = queue
        self.sd = None

    def run(self):
        try:
            self.start_serving()

        except KeyboardInterrupt:
            print("Shutting down..")

        finally:
            if self.sd is not None:
                self.sd.close()

    def start_serving(self):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.sd = s
        try:
            s.bind(('', self.port))
            s.listen(1)
            while True:
                conn, addr = s.accept()
                while True:
                    # I dont want to bore you with excess code
                    # just recv data from clients
                    try:
                        msg = self.queue.get_nowait()
                        # here i start Timer with delay from message (I'll describe Message class below)
                        Timer(msg.delay, self.response_handler, args=(conn, msg)).start()
                    except Empty:
                        pass
                conn.close()

        finally:
            s.close()

    def response_handler(self, sd, msg):
        # doesn't matter
        # and now I want to terminate the MyServer instance
        if msg.terminate:
            # the problem is here. Lets call it 'problem line'
            sys.exit()

msgMessage 类的一个实例,具体内容是:

class Message(object):
    def __init__(self, port, delay, values, terminate=False):
        self.port = port
        self.delay = delay
        self.values = values
        self.terminate = terminate

我的逻辑是通过 TCP 连接从客户端获取数据,然后检查消息队列。消息是用来控制服务器的东西。有时候我会收到像“等待 3 秒然后终止服务器”这样的消息。

到目前为止,我做了以下几件事:

  1. problem line 调用 self.terminate()。结果我得到了 AttributeError: 'NoneType' object has no attribute 'terminate' 的错误。
  2. problem line 抛出一个异常。我以为这个异常会在 run() 函数中被捕获,但我错了。
  3. 调用 sys.exit()。这也没有效果。

也许我的问题可以更简单一些。如何在 Python 中从线程中终止进程?

1 个回答

2

为什么不使用 multiprocessing.Event 呢(你已经导入了它)?如果收到终止消息,就可以优雅地退出进程。

要做到这一点,可以在 __init__ 方法中添加以下内容:

self.exit = Event()

然后修改这两个 while 循环:

while True:
    conn, addr = s.accept()
    while True:
    #...

改成:

while not self.exit.is_set():
    conn, addr = s.accept()
    while not self.exit.is_set()
    #...

接着在你的响应处理器中:

if msg.terminate:
    self.exit.set()

这样可以让代码自然地退出循环,确保调用 conn.close()

撰写回答