简体   繁体   English

从Timer线程终止进程

[英]Terminating process from Timer thread

I would better start the question from the code. 我最好从代码开始这个问题。

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()

msg is instance of Message class which is: msgMessage类的实例,它是:

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

The logic is I get data from clients via TCP connection and check Queue for message. 逻辑是我通过TCP连接从客户端获取数据,然后检查“队列”以获取消息。 Messages are things to control the server. 消息是控制服务器的事物。 Sometimes I get a message like "wait 3 seconds and terminate the server". 有时我会收到类似“等待3秒并终止服务器”的消息。 What I have done so far. 到目前为止我所做的。

  1. Call self.terminate() at the problem line . problem line调用self.terminate() I get AttributeError: 'NoneType' object has no attribute 'terminate' 我得到AttributeError: 'NoneType' object has no attribute 'terminate'
  2. Raise an exception at the problem line . problem line提出一个例外。 I assumed the exception was caught in run() function. 我认为该异常是在run()函数中捕获的。 I was wrong 我错了
  3. Call sys.exit() . 调用sys.exit() It doesn't work too. 它也不起作用。

Perhaps my question can be shorter. 也许我的问题可以更短。 How to terminate the process from its thread in Python? 如何在Python中从其线程终止进程?

Why don't you use multiprocessing.Event (you are already importing it) and exit the process gracefully if you get an terminate message. 如果收到终止消息,为什么不使用multiprocessing.Event (已经将其导入)并优雅地退出该过程。

To do this add this to __init__ : 为此,请将其添加到__init__

self.exit = Event()

And change the two while loops: 并更改两个while循环:

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

to

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

then in your response handler: 然后在您的响应处理程序中:

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

this will allow the code to naturally exit the loops, ensuring that conn.close() is called. 这将使代码自然退出循环,确保conn.close()被调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM