Как завершить поток в Python

#python #multithreading

#python #многопоточность

Вопрос:

Я изучаю, как использовать асинхронный код в Python. Я хочу запустить подпроцесс и дождаться его завершения. Пока он выполняется, я хочу отслеживать среднюю загрузку процессора в потоке и печатать его в конце. Этот код работает, но кажется неправильным постоянно проверять Popen.poll() . Есть ли лучший способ сделать это? Я хотел использовать Popen.wait() , но я не знаю, как сигнализировать другой функции о выходе из цикла.

В этом примере я использую yes в качестве тестового процесса, и через несколько секунд я завершаю его в терминале.

 def monitor(proc):
    cpu_percents = []
    while True:
        time.sleep(1)
        cpu_percents.append(psutil.cpu_percent())
        if proc.poll():
            return sum(cpu_percents) / len(cpu_percents)

def main():
    with ThreadPoolExecutor() as executor:
        proc = subprocess.Popen('yes', stdout=subprocess.DEVNULL)
        thread = executor.submit(monitor, proc)
        cpu_avg = thread.result()

    print('Average CPU usage was {:.1f}%'.format(cpu_avg))
  

Комментарии:

1. Обычно потоки используются как альтернатива асинхронному коду (в смысле кода, основанного на асинхронных / неблокирующих интерфейсах системного вызова). Похоже, что это просто потоковая передача, а не то, что обычно называется асинхронным.

2. В любом случае, сигнализация другому потоку — это одно, но у вас есть другой процесс , который вы хотите сигнализировать (и вы можете сигнализировать об этом из любого потока, потенциально включая основной).

3. Popen немедленно возвращается, пока yes все еще выполняется. Разве это не асинхронно?

4. Да, но это не то, что люди имеют в виду, когда они обычно говорят об асинхронном программировании. Запуск двух процессов способом, который не является синхронным, — это не то, для чего вам нужна асинхронная платформа или асинхронные системные вызовы. Что делает такие инструменты, как Twisted Python и преемники, особенными / интересными, так это поддержка написания кода, который мультиплексирует обработку нескольких подключений (amp; c), каждое из которых имеет свое собственное состояние и позицию в потоке управления приложения, в то время как фактически имеет только один поток управления на уровне ОС.

5. О, я понимаю. Ну, здесь подпроцесс завершится сам по себе. Я пытаюсь выяснить, как сигнализировать функции монитора о возврате, используя Popen.wait() внутри main