Многопоточное программирование и вызов внешних программ

Запуска многопоточного выполнения функции через ThreadPoolExecutor

from time import sleep
from concurrent.futures import ThreadPoolExecutor

def work(i):
    sleep(1)
    return f'Task {i} is complete'

data = list(range(8))

results = []

with ThreadPoolExecutor(2) as executor:
    for result in executor.map(work, data):
        print(result)
        results.append(result)
        
print(results)

Исполнение внешних программ

Запуск с ожиданием завершения

Простейший метод запуска программы метод os.system:

import os

ret = os.system("dir")
# ret - код завершения программы
# 0 - успешно, иначе ошибка

Вызов блокирующий - программа ждет завершения команды вызванной через os.system.

Запуск с получением вывода

import subprocess

output = subprocess.check_output('ping 127.0.0.1 -n 6', encoding="cp866")

print(output)

Вызов блокирующий - программа ждет завершения команды вызванной через subprocess.check_output.

Запуск без ожидания завершения

Метод subprocess.Popen по умолчанию запускает процесс без ожидания завершения:

import subprocess

q = subprocess.Popen("ping 127.0.0.1 -n 6", shell=True)

while q.poll() is None:
    print('waiting...')
    sleep(1)
 
print("Finished with code", q.poll())

Что еще нужно знать о запуске внешних программ

  • Если вы нажимаете Ctrl-C пока внешняя программа запущена через os.system, то этот сигнал уйдет ей, а не Python.
  • Можно взаимодействовать с интерактивными консольными приложениями пока те запущены через Popen. В частности их можно принудительно завершить или прочитать вывод до завершения самой программы.
  • Большинство приложений с графическим интерфейсом в качестве первого и единственного аргумента принимают имя файла, который должен быть в них открыт.