Как запустить несколько функций параллельно, если я не знаю заранее количество этих функций?

У меня есть таблица в БД. Каждая строчка соответствует отдельной камере и содержит для неё различные исходные данные: rtsp-ссылка, id чата, описание и так далее. При этом все функции get_camera идентичны, различаются только аргументы, которые в данный момент я прописал внутри них.

В данный момент у меня реализован такой рабочий вариант:

import concurrent.futures

if __name__ == '__main__':
    with concurrent.futures.ThreadPoolExecutor(max_workers=7) as executor:
        futures = [
            executor.submit(get_camera_1),
            executor.submit(get_camera_2),
            executor.submit(get_camera_3),
            executor.submit(get_camera_4),
        ]

        for future in concurrent.futures.as_completed(futures):
            try:
                future.result()
            except Exception as exc:
                print(f'Generated an exception: {exc}')

Но теперь в ту таблицу БД могут добавляться новые камеры, а, значит, количество функций может составлять уже не 4, а 10, 20, 50. То есть количеству функций get_camera будет равно количество строк в таблице.

Вопрос: как задать множество функций get_camera в таком случае?

У меня была мысль задать функции в цикле, чтобы получить список futures, но как добавить заданную функцию в этот список?


Ответы (1 шт):

Автор решения: Amgarak

Можно просто оформить генератор списка (задач), где каждая задача будет ссылаться на одну и ту же функцию, входные параметры при этом без проблем могут отличаться:

import concurrent.futures
import time

def get_camera(name, id_cam, description):
    time.sleep(1)
    print(f"Camera: {name}, ID: {id_cam}, Description: {description}\n")


def get_cameras():
    cameras = [
        ("camera1", 12345, "1 Camera"),
        ("camera2", 67890, "2 Camera"),
        ("camera3", 54321, "3 Camera"),
        ("camera4", 98765, "4 Camera"),
        # Чтото вроде тестовых данных\подключение к бд и т.д...
    ]
    return cameras

if __name__ == '__main__':
    cameras = get_cameras()

    with concurrent.futures.ThreadPoolExecutor(max_workers=7) as executor:
        futures = [
            executor.submit(get_camera, name, id_cam, description)
            for name, id_cam, description in cameras
        ]

        for future in concurrent.futures.as_completed(futures):
            try:
                future.result()
            except Exception as exc:
                print(f'Generated an exception: {exc}')

Вывод:

Camera: camera1, ID: 12345, Description: 1 Camera
Camera: camera4, ID: 98765, Description: 4 Camera
Camera: camera2, ID: 67890, Description: 2 Camera
Camera: camera3, ID: 54321, Description: 3 Camera
→ Ссылка