Многопроцессорный пул потоков объединяет аргументы - PullRequest
0 голосов
/ 26 июня 2018

У меня очень длинный список data, давайте предположим, что это выглядит так:

[(a, a, 1),
(b, b, 1),
(c, c, 1),
(d, d, 1),
(e, e, 1),
(f, f, 1),
(g, g, 1),
(h, h, 1),
(i, i, 1),]

Я пытаюсь использовать многопоточность следующим образом:

from multiprocessing.dummy import Pool as ThreadPool
pool = ThreadPool(4)
pool.starmap(help_func, data)

Help_func выглядит следующим образом:

def help_func(in_vala, in_valb, in_valc):
    print("asking for " + str(in_vala) + " asking for " + str(in_valb))
    receiver(in_vala)

, а приемник - это простая тестовая функция:

def receiver(group):
    print(group)

Когда я запускаю свою программу, я вижу, что вывод help_func является правильным, то есть он перечисляет значения data.

Однако, когда я смотрю на значения, сгенерированные в приемнике (), я замечаю некоторые странные отпечатки, которые выглядят так:

a
b
c
de
e
f
gh
i

Я изо всех сил пытаюсь понять, почему это может иметь место. Есть что-то, что идет не так при вызове приемника, возможно, из-за приведения приемника неблокирование может быть?

Как мне обойти эту проблему.

Кроме того, когда я использую ThreadPool (1), я не вижу этой проблемы. Моя настоящая проблема имеет гораздо большую функцию, которая вызывается из help_func, поэтому я хотел бы в идеале запустить ее в нескольких потоках.

1 Ответ

0 голосов
/ 26 июня 2018

Вы столкнулись с классической проблемой параллелизма: все, что вы считаете атомарным, не является.На самом деле функция print печатает две вещи: данные, которые вы передаете ей, и аргумент end, который по умолчанию равен "\n".

. Таким образом, конкатенация является результатом записи данных одним потоком, а затем других данных записи.затем оба пишут новые строки.

Все это гораздо лучше объяснено в этом выступлении Раймона Хеттингера .

PS: Я надеюсь, что вы знаете о Python GIL.Вкратце: только одна инструкция Python может выполняться одновременно во всех потоках Python.Если вы хотите ускорить выполнение вашей функции - используйте многопроцессорность, многопоточность полезна, когда ваш поток блокирует большую часть времени (например, сеть в основном ожидает поступления пакетов, поэтому потоки в порядке)

...