переменное количество потоков

#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) .