#python #multithreading #threadpool
#python #многопоточность #пул потоков
Вопрос:
я хочу иметь переменное количество потоков, которые выполняются одновременно. Я протестировал несколько многопоточных примеров из многопроцессорной обработки, но они не выполняются одновременно. Чтобы лучше объяснить это, приведите пример:
from multiprocessing import Pool
def f(x):
print("a",x)
time.sleep(1)
print("b",x)
if __name__ == '__main__':
with Pool(3) as p:
for i in range(5):
p.map(f, [i])
Результат:
a 0
b 0
a 1
b 1
a 2
b 2
Здесь он выполняет a, ожидает 1 секунду, а затем b, но я хочу, чтобы сначала печатались все a, а затем b (чтобы каждый поток выполнялся одновременно, чтобы результат выглядел так:
a0
a1
a2
b0
b1
b2
Комментарии:
1. Пожалуйста, посмотрите для начала: dev.to/nbosco/multithreading-vs-multiprocessing-in-python—63j .
Ответ №1:
Вы упомянули потоки, но, похоже, используете процессы. Модуль обработки потоков использует потоки, модуль многопроцессорной обработки использует процессы. Основное отличие заключается в том, что потоки выполняются в одном и том же пространстве памяти, в то время как процессы имеют отдельную память. Если вы хотите использовать библиотеку процессов. Попробуйте использовать приведенный ниже фрагмент кода.
from multiprocessing import Process
import time
def f(x):
print("a",x)
time.sleep(1)
print("b",x)
if __name__ == '__main__':
for i in range(5):
p = Process(target=f, args=(i,))
p.start()
процессы создаются путем создания объекта Process и последующего вызова его метода start() .
Комментарии:
1. Спасибо, код работает просто отлично, но у меня есть вопрос. Как я могу «синхронизировать» переменную со всеми потоками? Пример: `время импорта из многопроцессорного процесса импорта test_variable = 0 def f(x): глобальная test_variable print(«a», x) test_variable = 1 time.sleep(1) print(test_variable,»b», x) if name == ‘ main ‘: для i в диапазоне(5): p = Process(target= f, args =(i,)) p.start() ` Результат: a 0 a 1 a 2 a 3 a 4 1 b 0 1 b 1 1 b 2 1 b 3 1 b 4 Но это должно быть 4 b 0 4b 1…
2. Я думаю, вы имели в виду использовать общий счетчик с несколькими процессами. Я надеюсь, что это поможет eli.thegreenplace.net/2012/01/04 /…
Ответ №2:
Прежде всего, это не пул потоков, а пул процессов. Если вам нужны потоки, вам нужно использовать multiprocessing.dummy
.
Во-вторых, похоже, вы неправильно map
поняли метод. Самое главное, это блокировка. Вы вызываете его с одним нумерованным списком каждый раз — [i]
. Таким образом, вы на самом деле не используете Pool
полномочия. Вы используете только один процесс, ждете его завершения и переходите к следующему номеру. Чтобы получить желаемый результат, вы должны вместо этого сделать:
if __name__ == '__main__':
with Pool(3) as p:
p.map(f, range(5))
Но обратите внимание, что в этом случае у вас есть гонка между количеством процессов и диапазоном. Если вам нужны все a
s и только затем все b
s, попробуйте использовать Pool(5)
.