В приведенном ниже коде целые числа просто удваиваются, поэтому можно выполнить любое чистое вычисление. Это модуль, который должен выполняться execnet. Он получает 2 кортежа (i, arg), предполагает, что arg — это число, и отправляет обратно (i, arg * 2).
Код:
|
Для использования этот модуль для дублирования каждого элемента в списке, импортируйте модуль plists и вызовите plists .map() wi th модуль remote_double и список целых чисел для удвоения.
Код: использование plist
import
plists, remote_double
plists.
map
(remote_double,
range
(
10
))
Вывод:
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
Карта ( ) определена в plists.py. Он принимает чистый модуль, список аргументов и необязательный список из двух кортежей (spec, count). По умолчанию используются спецификации [(' popen ', 2)], что означает, что пользователь откроет два локальных шлюза и канала. Как только эти каналы открыты, пользователь может поместить их в цикл itertools, который создает бесконечный итератор, который возвращается к началу, как только достигает конца.
Теперь каждый аргумент может быть отправлен в качестве аргументов. в трубу для обработки, а так как каналы цикличны, то каждый канал получает почти равное распределение аргументов. Вот где я появился — порядок, в котором возвращаются результаты, неизвестен, поэтому i в качестве индекса каждого аргумента в списке передается в канал и из него, чтобы пользователь мог комбинировать результаты в исходном порядке. . Затем дождитесь результатов с очередью приема MultiChannel и вставьте их в предварительно заполненный список той же длины, что и исходные аргументы. После получения всех ожидаемых результатов выйдите из шлюзов и верните результаты, как показано в приведенном ниже коде —
Код:
import
itertools, execnet
def
map
(mod, args, specs
=
[(
`popen`
,
2
)]):
шлюзы
=
[]
каналы
=
[]
для
спецификация, количество
в
спецификации:
для
i
для
диапазон
(количество):
gw
=
execnet.makegateway (spec)
gateways.append (gw )
channels.append (gw.remote_exec (mod))
cyc
=
itertools.cycle (каналы)
for
i, arg
in
enumerate
(аргументы):
канал
=
следующий
(cyc )
channel.send ((i, arg))
mch
=
execnet.MultiChannel (каналы)
очередь
=
mch.make_receive_queue ()
l
=
len
(args)
# создает список длиной l,
# где каждый элемент равен None
результаты
=
None
]
*
l
for
i
in
range
(l):
канал, (i, результат)
=
queue.get ()
results [i]
=
result
для
gw
в
шлюзы:
gw.exit ()
return
результаты
Код: улучшите распараллеливание, изменив спецификацию
списки.
map
(remote_double,
range
(
10
), [(
`popen`
,
4
)])
Вывод:
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
Однако отсутствие распараллеливания обязательно означает более быструю обработку. Это зависит от доступных ресурсов, и чем больше шлюзов и каналов открыто, тем больше накладных расходов. В идеале должен быть один шлюз и канал на ядро ЦП, чтобы максимизировать использование ресурсов. Используйте plists.map() с любым чистым модулем, если он получает и отправляет обратно 2 кортежа, где i — первый элемент. Этот шаблон наиболее полезен, когда необходимо обработать много чисел, чтобы обработать их как можно быстрее.