我无法在中断事件中停止此守护进程线程

时间:2019-02-20 06:51:48

标签: python multithreading redis daemon python-multithreading

我试图在Python中运行一堆守护进程线程,并处理按Ctrl + C或中断时要触发的信号。我第一次启动它只有一个线程在运行,第二次它只有2个线程,依此类推。它会继续生成线程,并且无法正确关闭它们。任何人都可以指出为什么worker.join在通话

中不起作用
# -*- coding: utf-8 -*-
"""
An example url status checker that uses events to stop threads.
"""

import threading
import queue
import signal
import sys
import requests
import time
import redis

# Create redis client
redis_client = redis.Redis()
pubsub = redis_client.pubsub()

# Subscribe to values channel
pubsub.subscribe("values")

class StatusChecker(threading.Thread):
    """
    The thread that will check HTTP statuses.
    """

    #: An event that tells the thread to stop
    stopper = None

    def __init__(self, stopper):
        super().__init__()
        self.stopper = stopper

#         Run the thread in daemon mode
        self.daemon = True


    def run(self):
        while not self.stopper.is_set():
            try:
#                 Infinitely listen to pubsub messages
                for message in pubsub.listen():
                    # this will throw queue.Empty immediately if there's
                    # no tasks left
                    print(message, self.getName())
            except Exception as e:
                print(e)


class SignalHandler:
    """
    The object that will handle signals and stop the worker threads.
    """

    #: The stop event that's shared by this handler and threads.
    stopper = None

    #: The pool of worker threads
    workers = None

    def __init__(self, stopper, workers):
        self.stopper = stopper
        self.workers = workers

    def __call__(self, signum, frame):
        """
        This will be called by the python signal module
        https://docs.python.org/3/library/signal.html#signal.signal
        """
        self.stopper.set()
#         Join the workers
        for worker in self.workers:
            worker.join()
        sys.exit(0)


if __name__ == '__main__':
    # all the variables we'll need
    num_workers = 1
    stopper = threading.Event()

    # we need to keep track of the workers but not start them yet
    workers = [StatusChecker(stopper) for i in range(num_workers)]

    # create our signal handler and connect it
    handler = SignalHandler(stopper, workers)
    signal.signal(signal.SIGINT, handler)

    # start the threads!
    for i, worker in enumerate(workers):
        print('Starting worker {}'.format(i))
        worker.start()

0 个答案:

没有答案