python - как запустить фоновый поток без остановки основного потока - PullRequest
0 голосов
/ 02 августа 2020

Этот простой пример кода:

import threading
import time


class Monitor():

    def __init__(self):
        self.stop = False
        self.blocked_emails = []

    def start_monitor(self):
        print("Run start_monitor")
        rows = []
        while not self.stop:
            self.check_rows(rows)
            print("inside while")
            time.sleep(1)

    def check_rows(self, rows):
        print('check_rows')

    def stop_monitoring(self):
        print("Run stop_monitoring")
        self.stop = True


if __name__ == '__main__':
    monitor = Monitor()

    b = threading.Thread(name='background_monitor', target=monitor.start_monitor())
    b.start()
    b.join()

    for i in range(0, 10):
        time.sleep(2)
        print('Wait 2 sec.')
    monitor.stop_monitoring()

Как я могу запустить фоновый поток, в моем случае background_monitor без блокировки основного потока?

Я хотел, чтобы background_monitor поток остановился на после того, как stop_monitoring будет вызываться

Я мой пример, for l oop из основного потока никогда не вызывался, а фон работает вечно.

1 Ответ

1 голос
/ 02 августа 2020

Есть две проблемы с вашим текущим кодом. Во-первых, вы вызываете monitor.start_monitor в этой строке, тогда как согласно цель документации

- это вызываемый объект, который будет вызываться методом run (). По умолчанию None означает, что ничего не вызывается.

Это означает, что вам нужно передать его как функцию, а не вызывать. Чтобы исправить это, вы должны изменить строку

b = threading.Thread(name='background_monitor', target=monitor.start_monitor())

на

b = threading.Thread(name='background_monitor', target=monitor.start_monitor)

, которая передает функцию в качестве аргумента.

Во-вторых, вы используете b.join() перед остановкой потока, который ожидает, пока второй поток завершит sh, прежде чем продолжить. Вместо этого вы должны поместить это под monitor.stop_monitoring().

Исправленный код выглядит следующим образом:

import threading
import time


class Monitor():

    def __init__(self):
        self.stop = False
        self.blocked_emails = []

    def start_monitor(self):
        print("Run start_monitor")
        rows = []
        while not self.stop:
            self.check_rows(rows)
            print("inside while")
            time.sleep(1)

    def check_rows(self, rows):
        print('check_rows')

    def stop_monitoring(self):
        print("Run stop_monitoring")
        self.stop = True


if __name__ == '__main__':
    monitor = Monitor()

    b = threading.Thread(name='background_monitor', target=monitor.start_monitor)
    b.start()

    for i in range(0, 10):
        time.sleep(2)
        print('Wait 2 sec.')
    monitor.stop_monitoring()
    b.join()
...