Решение уравнения с помощью threading

прошу вашей помощи, никак не могу въехать в threading... Например есть уравнение вида y=x^2 + 4x, т.е. части x^2 и 4x мы можем вычислить независимо (в разных потоках, поправьте если я ошибаюсь терминологией). Я начал писать код, но никак не могу понять как из функций в потоке вернуть y1 и y2 что бы их потом сложить?

import threading

# Посчитаем уравнение y=x **2 + 4*x

def square_number(x):
    y1 = x ** 2
    return y1


def quadruple_num(x):
    y2 = 4 * x
    return y2

# допустим x = 2
x= 2

t1 = threading.Thread(target=square_number, args=(x,))
t2 = threading.Thread(target=quadruple_num, args=(x,))
t1.start()
t2.start()
t1.join()
t2.join()

# Как получить у1 и у2 чтобы их сложить?

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

Автор решения: Andy Pavlov

Вариант передавать в поток список или словарь, которые наполнять результатами, а потом уже обрабатывать это список/словарь.

В частности я сделал обертку, в которую завожу функцию, список для результатов и переменные. Внутри обертки вычисляем результат и добавляем его в результирующий список. В конце суммирую значения.

import threading

# Посчитаем уравнение y=x **2 + 4*x

def square_number(x):
    y1 = x ** 2
    return y1


def quadruple_num(x):
    y2 = 4 * x
    return y2


def wrapme(func, res, *args, **kwargs):
    res.append(func(*args, **kwargs))


# допустим x = 2
x = 2
res = []

t1 = threading.Thread(target=wrapme, args=(square_number, res, x,))
t2 = threading.Thread(target=wrapme, args=(quadruple_num, res, x,))
t1.start()
t2.start()
t1.join()
t2.join()

print(sum(res))  # 12
→ Ссылка
Автор решения: CrazyElf

Ещё вариант через concurrent.futures.ThreadPoolExecutor:

from concurrent.futures import ThreadPoolExecutor

def square_number(x):
    y1 = x ** 2
    return y1

def quadruple_num(x):
    y2 = 4 * x
    return y2

for x in range(5):
    with ThreadPoolExecutor() as executor:
        futures = [executor.submit(func, x) for func in [square_number, quadruple_num]]
        result = sum(f.result() for f in futures)
        print(x, result)

Вывод:

0 0
1 5
2 12
3 21
4 32

Подсмотрено мной тут.

Выглядит довольно прозрачно:

  • открываем пул потоков
  • отправляем туда функции и аргументы
  • собираем результаты работы
  • пул закрывается автоматом, поскольку открыт через with
→ Ссылка