【问题标题】:Stopping a server in a subprocess with its shutdown method使用其关闭方法停止子进程中的服务器
【发布时间】:2019-05-28 14:08:22
【问题描述】:

我在 Windows 10 上的 CPython 3.7 中实现了一个 Server 类,其中 Server.serve 方法可以永久启动服务,Server.shutdown 方法可以停止服务。我需要在子进程中运行多个服务器实例。

在子线程中运行服务器实例会按预期停止实例:

import threading
import time


class Server:

    def __init__(self):
        self.shutdown_request = False

    def serve(self):
        print("serving")

        while not self.shutdown_request:
            print("hello")
            time.sleep(1)

        print("done")

    def shutdown(self):
        print("stopping")
        self.shutdown_request = True


if __name__ == "__main__":
    server = Server()
    threading.Thread(target=server.serve).start()
    time.sleep(5)
    server.shutdown()

但是,在子进程中运行服务器实例并不会意外地停止该实例:

import multiprocessing
import time


class Server:

    def __init__(self):
        self.shutdown_request = False

    def serve(self):
        print("serving")

        while not self.shutdown_request:
            print("hello")
            time.sleep(1)

        print("done")

    def shutdown(self):
        print("stopping")
        self.shutdown_request = True


if __name__ == "__main__":
    server = Server()
    multiprocessing.Process(target=server.serve).start()
    time.sleep(5)
    server.shutdown()

我怀疑在多进程的情况下,self.shutdown_request属性在父进程和子进程之间没有共享,因此server.shutdown()调用不会影响子进程中正在运行的服务器实例。

我知道我可以用 multiprocessing.Event 解决这个问题:

import multiprocessing
import time


class Server:

    def __init__(self, shutdown_event):
        self.shutdown_event = shutdown_event

    def serve(self):
        print("serving")

        while not self.shutdown_event.is_set():
            print("hello")
            time.sleep(1)

        print("done")


if __name__ == "__main__":
    shutdown_event = multiprocessing.Event()
    server = Server(shutdown_event)
    multiprocessing.Process(target=server.serve).start()
    time.sleep(5)
    shutdown_event.set()

但我想保留Server.shutdown 方法,而不是根据其用法更改Server 接口(单处理v. 多处理),我不希望客户处理@ 987654332@.

【问题讨论】:

    标签: python server multiprocessing shutdown


    【解决方案1】:

    我终于自己想出了一个解决办法:

    import multiprocessing
    import time
    
    
    class Server:
    
        def __init__(self):
            self.shutdown_event = multiprocessing.Event()
    
        def serve(self):
            print("serving")
    
            while not self.shutdown_event.is_set():
                print("hello")
                time.sleep(1)
    
            print("done")
    
        def shutdown(self):
            print("stopping")
            self.shutdown_event.set()
    
    
    if __name__ == "__main__":
        server = Server()
        multiprocessing.Process(target=server.serve).start()
        time.sleep(5)
        server.shutdown()
    

    它适用于任何一种情况:单处理(多线程)和多处理。

    备注。 — 在 __init__ 方法中使用 multiprocessing.Event() 时,Server 实例不再可以选择。如果想在进程池中调用Server 实例(使用multiprocessing.pool.Poolconcurrent.futures.ProcessPoolExecutor),这可能是个问题。在这种情况下,应该在__init__ 方法中将multiprocessing.Event() 替换为multiprocessing.Manager().Event()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-09-23
      • 2023-03-02
      • 2019-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多