#python #multithreading
Вопрос:
Если мне нужно выполнить задачу 5 раз, и обычно это занимает 10-30 секунд на каждую задачу, гарантирует ли это, что я сразу начну все 5 в отдельных потоках?
with ThreadPoolExecutor(max_workers=5) as executor:
results = list(executor.map(task, [0, 1, 2, 3, 4]))
Если ответ отрицательный, то как бы я получил желаемую гарантию?
Комментарии:
1. @user207421 так и есть. Просто не хватает места, чтобы полностью указать… Моя заметка просто спасает отвечающего от написания эссе.
2. @user207421 так и есть. Это более конкретно. Это не значит, что название не отражает мой реальный вопрос. Не могли бы вы предложить внести правку?
3. Я уже предлагал вам заставить их согласиться. Я также предлагаю, чтобы ответ на вопрос в вашем названии был «нет, если это явно не указано», но соответствие вашего названия вашему вопросу зависит от вас. Это в ваших же интересах-привлечь нужных читателей. Я не зарабатываю на этом ни цента.
Ответ №1:
Ничто в жизни не гарантировано, но можно с уверенностью утверждать, что каждая задача будет выполняться в отдельных потоках в пуле потоков.
Пять отправленных задач попадают во входную очередь задач, которые необходимо выполнить. Если бы рабочая функция task
выполнялась очень быстро, теоретически было бы возможно , чтобы один из потоков в пуле потоков извлек из очереди входных задач все задачи и запустил их одну за другой до того, как у любого из остальных 4 потоков появилась возможность запустить. Но, учитывая, что у нас есть относительно длительная задача, всем 5 потокам будет предоставлен временной отрезок, прежде чем какой-либо один поток сможет завершить выполнение хотя бы одной задачи.
Вот пример чрезвычайно сложной задачи ввода-вывода:
from concurrent.futures import ThreadPoolExecutor
def task(x):
import threading
import time
time.sleep(2)
print(threading.get_ident(), x)
with ThreadPoolExecutor(max_workers=5) as executor:
results = list(executor.map(task, [0, 1, 2, 3, 4]))
С принтами:
15492 0
21120 1
3160 2
12548 3
13468 4
И вот пример чрезвычайно сложной задачи, связанной с процессором:
from concurrent.futures import ThreadPoolExecutor
ONE_SECOND_ITERATIONS = 20_000_000
def one_second():
sum = 0
for _ in range(ONE_SECOND_ITERATIONS):
sum = 1
return sum
def task(x):
import threading
for _ in range(2):
one_second()
print(threading.get_ident(), x)
with ThreadPoolExecutor(max_workers=5) as executor:
results = list(executor.map(task, [0, 1, 2, 3, 4]))
С принтами:
14660 0
21776 4
3384 3
16596 1
4924 2
Вот случай, когда task
выполняется чрезвычайно быстро, и один поток выполняет все 5 задач:
from concurrent.futures import ThreadPoolExecutor
def task(x):
import threading
return (threading.get_ident(), x)
with ThreadPoolExecutor(max_workers=5) as executor:
results = list(executor.map(task, [0, 1, 2, 3, 4]))
print(results)
С принтами:
[(18104, 0), (18104, 1), (18104, 2), (18104, 3), (18104, 4)]
Комментарии:
1. Отлично! Спасибо за все примеры.