Python đa xử lý pool.map cho nhiều đối số


536

Trong thư viện đa xử lý Python, có một biến thể của pool.map hỗ trợ nhiều đối số không?

text = "test"
def harvester(text, case):
    X = case[0]
    text+ str(X)

if __name__ == '__main__':
    pool = multiprocessing.Pool(processes=6)
    case = RAW_DATASET
    pool.map(harvester(text,case),case, 1)
    pool.close()
    pool.join()

4
Trước sự ngạc nhiên của tôi, tôi có thể làm cho không partialcũng không lambdalàm điều này. Tôi nghĩ rằng nó phải làm theo cách kỳ lạ là các chức năng được truyền cho các quy trình con (thông qua pickle).
gửi

10
@senderle: Đây là một lỗi trong Python 2.6, nhưng đã được sửa chữa kể từ ngày 2.7: bug.python.org/su5228
unutbu

1
Chỉ cần thay thế pool.map(harvester(text,case),case, 1) bằng cách: pool.apply_async(harvester(text,case),case, 1)
Tung Nguyen

3
@Syrtis_Major, vui lòng không chỉnh sửa các câu hỏi OP có hiệu quả làm lệch các câu trả lời đã được đưa ra trước đó. Thêm vào returnđể harvester()biến phản ứng của @senderie thành không chính xác. Điều đó không giúp ích cho độc giả trong tương lai.
Ricalsin

1
Tôi muốn nói giải pháp dễ dàng là đóng gói tất cả các đối số trong một tuple và giải nén nó trong func thực thi. Tôi đã làm điều này khi tôi cần gửi nhiều đối số phức tạp đến một func đang được thực thi bởi một nhóm các quy trình.
HS Rathore

Câu trả lời:


358

Câu trả lời cho điều này là phụ thuộc vào phiên bản và tình huống. Câu trả lời chung nhất cho các phiên bản gần đây của Python (kể từ 3.3) lần đầu tiên được mô tả dưới đây bởi JF Sebastian . 1 Nó sử dụng Pool.starmapphương thức chấp nhận một chuỗi các bộ đối số. Sau đó, nó sẽ tự động giải nén các đối số từ mỗi bộ dữ liệu và chuyển chúng đến hàm đã cho:

import multiprocessing
from itertools import product

def merge_names(a, b):
    return '{} & {}'.format(a, b)

if __name__ == '__main__':
    names = ['Brown', 'Wilson', 'Bartlett', 'Rivera', 'Molloy', 'Opie']
    with multiprocessing.Pool(processes=3) as pool:
        results = pool.starmap(merge_names, product(names, repeat=2))
    print(results)

# Output: ['Brown & Brown', 'Brown & Wilson', 'Brown & Bartlett', ...

Đối với các phiên bản trước của Python, bạn sẽ cần viết hàm trợ giúp để giải nén các đối số một cách rõ ràng. Nếu bạn muốn sử dụng with, bạn cũng cần phải viết một trình bao bọc để biến Poolthành trình quản lý bối cảnh. (Cảm ơn muon vì đã chỉ ra điều này.)

import multiprocessing
from itertools import product
from contextlib import contextmanager

def merge_names(a, b):
    return '{} & {}'.format(a, b)

def merge_names_unpack(args):
    return merge_names(*args)

@contextmanager
def poolcontext(*args, **kwargs):
    pool = multiprocessing.Pool(*args, **kwargs)
    yield pool
    pool.terminate()

if __name__ == '__main__':
    names = ['Brown', 'Wilson', 'Bartlett', 'Rivera', 'Molloy', 'Opie']
    with poolcontext(processes=3) as pool:
        results = pool.map(merge_names_unpack, product(names, repeat=2))
    print(results)

# Output: ['Brown & Brown', 'Brown & Wilson', 'Brown & Bartlett', ...

Trong các trường hợp đơn giản hơn, với một đối số thứ hai cố định, bạn cũng có thể sử dụng partial, nhưng chỉ trong Python 2.7+.

import multiprocessing
from functools import partial
from contextlib import contextmanager

@contextmanager
def poolcontext(*args, **kwargs):
    pool = multiprocessing.Pool(*args, **kwargs)
    yield pool
    pool.terminate()

def merge_names(a, b):
    return '{} & {}'.format(a, b)

if __name__ == '__main__':
    names = ['Brown', 'Wilson', 'Bartlett', 'Rivera', 'Molloy', 'Opie']
    with poolcontext(processes=3) as pool:
        results = pool.map(partial(merge_names, b='Sons'), names)
    print(results)

# Output: ['Brown & Sons', 'Wilson & Sons', 'Bartlett & Sons', ...

1. Phần lớn điều này được lấy cảm hứng từ câu trả lời của anh ấy, có lẽ nên được chấp nhận thay thế. Nhưng vì cái này bị kẹt ở đầu, có vẻ như tốt nhất để cải thiện nó cho độc giả trong tương lai.


Dường như với tôi rằng RAW_DATASET trong trường hợp này phải là một biến toàn cục? Trong khi tôi muốn part_harvester thay đổi giá trị của case trong mỗi lệnh gọi của máy gặt (). Làm thế nào để đạt được điều đó?
xgdgsc

Điều quan trọng nhất ở đây là gán =RAW_DATASETgiá trị mặc định cho case. Nếu không pool.mapsẽ nhầm lẫn về nhiều đối số.
Emerson Xu

1
Tôi bối rối, điều gì đã xảy ra với textbiến trong ví dụ của bạn? Tại sao RAW_DATASETdường như được thông qua hai lần. Tôi nghĩ rằng bạn có thể có một lỗi đánh máy?
Dave

không chắc chắn tại sao việc sử dụng with .. as .. mang lại cho tôi AttributeError: __exit__, nhưng hoạt động tốt nếu tôi chỉ gọi pool = Pool();rồi đóng thủ công pool.close()(python2.7)
muon

1
@muon, bắt tốt. Có vẻ như Poolcác đối tượng không trở thành người quản lý bối cảnh cho đến khi Python 3.3. Tôi đã thêm một hàm bao bọc đơn giản trả về trình Poolquản lý bối cảnh.
gửi

501

Có một biến thể của pool.map hỗ trợ nhiều đối số không?

Python 3.3 bao gồm pool.starmap()phương thức :

#!/usr/bin/env python3
from functools import partial
from itertools import repeat
from multiprocessing import Pool, freeze_support

def func(a, b):
    return a + b

def main():
    a_args = [1,2,3]
    second_arg = 1
    with Pool() as pool:
        L = pool.starmap(func, [(1, 1), (2, 1), (3, 1)])
        M = pool.starmap(func, zip(a_args, repeat(second_arg)))
        N = pool.map(partial(func, b=second_arg), a_args)
        assert L == M == N

if __name__=="__main__":
    freeze_support()
    main()

Đối với phiên bản cũ hơn:

#!/usr/bin/env python2
import itertools
from multiprocessing import Pool, freeze_support

def func(a, b):
    print a, b

def func_star(a_b):
    """Convert `f([1,2])` to `f(1,2)` call."""
    return func(*a_b)

def main():
    pool = Pool()
    a_args = [1,2,3]
    second_arg = 1
    pool.map(func_star, itertools.izip(a_args, itertools.repeat(second_arg)))

if __name__=="__main__":
    freeze_support()
    main()

Đầu ra

1 1
2 1
3 1

Lưu ý cách itertools.izip()itertools.repeat()được sử dụng ở đây.

Do lỗi được đề cập bởi @unutbu, bạn không thể sử dụng functools.partial()hoặc các khả năng tương tự trên Python 2.6, do đó, chức năng trình bao bọc đơn giản func_star()phải được xác định rõ ràng. Xem thêm cách giải quyết được đề xuất bởiuptimebox .


1
F.: Bạn có thể giải nén bộ đối số trong chữ ký func_starnhư thế này : def func_star((a, b)). Tất nhiên, điều này chỉ hoạt động cho một số lượng đối số cố định, nhưng nếu đó là trường hợp duy nhất anh ta có, nó dễ đọc hơn.
Bjorn Pollex

1
@ Space_C0wb0y: f((a,b))cú pháp không được dùng nữa và bị xóa trong py3k. Và nó là không cần thiết ở đây.
jfs

có lẽ nhiều pythonic hơn: func = lambda x: func(*x)thay vì xác định chức năng bao bọc
dylam

1
@ zthomas.nc câu hỏi này là về cách hỗ trợ nhiều đối số cho đa xử lý pool.map. Nếu muốn biết cách gọi một phương thức thay vì một hàm trong một quy trình Python khác thông qua đa xử lý thì hãy đặt một câu hỏi riêng (nếu tất cả đều thất bại, bạn luôn có thể tạo một hàm toàn cầu bao bọc cuộc gọi phương thức tương tự như func_star()trên)
jfs

1
Tôi ước có starstarmap.
Toàn cảnh

141

Tôi nghĩ rằng dưới đây sẽ tốt hơn

def multi_run_wrapper(args):
   return add(*args)
def add(x,y):
    return x+y
if __name__ == "__main__":
    from multiprocessing import Pool
    pool = Pool(4)
    results = pool.map(multi_run_wrapper,[(1,2),(2,3),(3,4)])
    print results

đầu ra

[3, 5, 7]

16
Giải pháp dễ nhất. Có một tối ưu hóa nhỏ; loại bỏ chức năng bao bọc và giải nén argstrực tiếp add, nó hoạt động với bất kỳ số lượng đối số nào:def add(args): (x,y) = args
Ahmed

1
bạn cũng có thể sử dụng một lambdachức năng thay vì xác địnhmulti_run_wrapper(..)
Andre Holzner

2
hm ... trên thực tế, sử dụng một lambdakhông hoạt động vì pool.map(..)cố gắng chọn chức năng đã cho
Andre Holzner

Làm thế nào để bạn sử dụng điều này nếu bạn muốn lưu trữ kết quả addtrong một danh sách?
Vivek Subramanian

@Ahmed Tôi thích nó như thế nào, vì IMHO cuộc gọi phương thức sẽ thất bại, bất cứ khi nào số lượng tham số không chính xác.
Michael D Corner

56

Sử dụng Python 3.3+ vớipool.starmap():

from multiprocessing.dummy import Pool as ThreadPool 

def write(i, x):
    print(i, "---", x)

a = ["1","2","3"]
b = ["4","5","6"] 

pool = ThreadPool(2)
pool.starmap(write, zip(a,b)) 
pool.close() 
pool.join()

Kết quả:

1 --- 4
2 --- 5
3 --- 6

Bạn cũng có thể nén () nhiều đối số hơn nếu bạn muốn: zip(a,b,c,d,e)

Trong trường hợp bạn muốn có một giá trị không đổi được chuyển qua làm đối số bạn phải sử dụng import itertoolsvà sau đó là zip(itertools.repeat(constant), a)ví dụ.


2
Đây là một câu trả lời trùng lặp gần như chính xác như câu trả lời từ @JFSebastian năm 2011 (với hơn 60 phiếu).
Mike McKerns

29
Không. Trước hết, nó đã loại bỏ rất nhiều thứ không cần thiết và nêu rõ nó dành cho python 3.3+ và dành cho người mới bắt đầu tìm kiếm một câu trả lời đơn giản và rõ ràng. Là một người mới bắt đầu, tôi đã mất một thời gian để tìm ra cách đó (vâng với các bài đăng của JFSebastians) và đây là lý do tại sao tôi viết bài đăng của mình để giúp đỡ những người mới bắt đầu khác, bởi vì bài đăng của anh ấy chỉ đơn giản là "có starmap" nhưng không giải thích được - điều này là những gì bài viết của tôi dự định. Vì vậy, hoàn toàn không có lý do để bash tôi với hai downvote.
dùng136036

Trong năm 2011, không có "+" trong python 3.3 +.
Mike McKerns

27

Tìm hiểu về itertools trong câu trả lời của JF Sebastian, tôi quyết định tiến thêm một bước và viết một parmapgói quan tâm đến việc song song hóa, cung cấp mapvà các starmapchức năng trên python-2.7 và python-3.2 (và sau đó) có thể đưa ra bất kỳ số lượng đối số vị trí nào .

Cài đặt

pip install parmap

Cách song song:

import parmap
# If you want to do:
y = [myfunction(x, argument1, argument2) for x in mylist]
# In parallel:
y = parmap.map(myfunction, mylist, argument1, argument2)

# If you want to do:
z = [myfunction(x, y, argument1, argument2) for (x,y) in mylist]
# In parallel:
z = parmap.starmap(myfunction, mylist, argument1, argument2)

# If you want to do:
listx = [1, 2, 3, 4, 5, 6]
listy = [2, 3, 4, 5, 6, 7]
param = 3.14
param2 = 42
listz = []
for (x, y) in zip(listx, listy):
        listz.append(myfunction(x, y, param1, param2))
# In parallel:
listz = parmap.starmap(myfunction, zip(listx, listy), param1, param2)

Tôi đã tải parmap lên PyPI và vào kho lưu trữ github .

Ví dụ, câu hỏi có thể được trả lời như sau:

import parmap

def harvester(case, text):
    X = case[0]
    text+ str(X)

if __name__ == "__main__":
    case = RAW_DATASET  # assuming this is an iterable
    parmap.map(harvester, case, "test", chunksize=1)

20

# "Cách lấy nhiều đối số".

def f1(args):
    a, b, c = args[0] , args[1] , args[2]
    return a+b+c

if __name__ == "__main__":
    import multiprocessing
    pool = multiprocessing.Pool(4) 

    result1 = pool.map(f1, [ [1,2,3] ])
    print(result1)

2
Gọn gàng và thanh lịch.
Prav001

1
Tôi không hiểu tại sao tôi phải di chuyển khắp nơi để tìm câu trả lời hay nhất.
toti

11

Có một nhánh của các pathosmultiprocessing được gọi là ( lưu ý: sử dụng phiên bản trên github ) không cần - các chức năng bản đồ phản ánh API cho bản đồ của python, do đó bản đồ có thể có nhiều đối số. Với , bạn cũng thường có thể thực hiện đa xử lý trong trình thông dịch, thay vì bị mắc kẹt trong khối. Pathos chuẩn bị được phát hành, sau một số cập nhật nhẹ - chủ yếu là chuyển đổi sang python 3.x.starmappathos__main__

  Python 2.7.5 (default, Sep 30 2013, 20:15:49) 
  [GCC 4.2.1 (Apple Inc. build 5566)] on darwin
  Type "help", "copyright", "credits" or "license" for more information.
  >>> def func(a,b):
  ...     print a,b
  ...
  >>>
  >>> from pathos.multiprocessing import ProcessingPool    
  >>> pool = ProcessingPool(nodes=4)
  >>> pool.map(func, [1,2,3], [1,1,1])
  1 1
  2 1
  3 1
  [None, None, None]
  >>>
  >>> # also can pickle stuff like lambdas 
  >>> result = pool.map(lambda x: x**2, range(10))
  >>> result
  [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
  >>>
  >>> # also does asynchronous map
  >>> result = pool.amap(pow, [1,2,3], [4,5,6])
  >>> result.get()
  [1, 32, 729]
  >>>
  >>> # or can return a map iterator
  >>> result = pool.imap(pow, [1,2,3], [4,5,6])
  >>> result
  <processing.pool.IMapIterator object at 0x110c2ffd0>
  >>> list(result)
  [1, 32, 729]

pathoscó một số cách mà bạn có thể có được hành vi chính xác starmap.

>>> def add(*x):
...   return sum(x)
... 
>>> x = [[1,2,3],[4,5,6]]
>>> import pathos
>>> import numpy as np
>>> # use ProcessPool's map and transposing the inputs
>>> pp = pathos.pools.ProcessPool()
>>> pp.map(add, *np.array(x).T)
[6, 15]
>>> # use ProcessPool's map and a lambda to apply the star
>>> pp.map(lambda x: add(*x), x)
[6, 15]
>>> # use a _ProcessPool, which has starmap
>>> _pp = pathos.pools._ProcessPool()
>>> _pp.starmap(add, x)
[6, 15]
>>> 

Tôi muốn lưu ý rằng điều này không giải quyết cấu trúc trong câu hỏi ban đầu. [[1,2,3], [4,5,6]] sẽ giải nén bằng starmap thành [pow (1,2,3), pow (4,5,6)], chứ không phải [pow (1,4) , pow (2,5), pow (3, 6)]. Nếu bạn không kiểm soát tốt các đầu vào được chuyển đến chức năng của mình, bạn có thể cần phải cơ cấu lại chúng trước.
Scott

@Scott: ah, tôi đã không nhận thấy rằng ... hơn 5 năm trước. Tôi sẽ thực hiện một bản cập nhật nhỏ. Cảm ơn.
Mike McKerns

8

Bạn có thể sử dụng hai chức năng sau để tránh viết trình bao bọc cho mỗi chức năng mới:

import itertools
from multiprocessing import Pool

def universal_worker(input_pair):
    function, args = input_pair
    return function(*args)

def pool_args(function, *args):
    return zip(itertools.repeat(function), zip(*args))

Sử dụng chức năng functionvới danh sách các đối số arg_0, arg_1arg_2như sau:

pool = Pool(n_core)
list_model = pool.map(universal_worker, pool_args(function, arg_0, arg_1, arg_2)
pool.close()
pool.join()

8

Một giải pháp tốt hơn cho python2:

from multiprocessing import Pool
def func((i, (a, b))):
    print i, a, b
    return a + b
pool = Pool(3)
pool.map(func, [(0,(1,2)), (1,(2,3)), (2,(3, 4))])

2 3 4

1 2 3

0 1 2

ngoài[]:

[3, 5, 7]


7

Một cách khác đơn giản là bọc các tham số chức năng của bạn trong một tuple và sau đó cũng bọc các tham số cần được truyền trong các tuple. Điều này có lẽ không lý tưởng khi xử lý các phần dữ liệu lớn. Tôi tin rằng nó sẽ tạo bản sao cho mỗi bộ.

from multiprocessing import Pool

def f((a,b,c,d)):
    print a,b,c,d
    return a + b + c +d

if __name__ == '__main__':
    p = Pool(10)
    data = [(i+0,i+1,i+2,i+3) for i in xrange(10)]
    print(p.map(f, data))
    p.close()
    p.join()

Cung cấp đầu ra theo một số thứ tự ngẫu nhiên:

0 1 2 3
1 2 3 4
2 3 4 5
3 4 5 6
4 5 6 7
5 6 7 8
7 8 9 10
6 7 8 9
8 9 10 11
9 10 11 12
[6, 10, 14, 18, 22, 26, 30, 34, 38, 42]

Thật vậy, vẫn đang tìm kiếm một cách tốt hơn :(
Fábio Dias

6

Một cách tốt hơn là sử dụng trang trí thay vì viết chức năng bao bọc bằng tay. Đặc biệt là khi bạn có rất nhiều chức năng để lập bản đồ, trang trí sẽ tiết kiệm thời gian của bạn bằng cách tránh viết trình bao cho mọi chức năng. Thông thường một chức năng được trang trí là không thể chọn được, tuy nhiên chúng ta có thể sử dụng functoolsđể đi xung quanh nó. Nhiều thông tin có thể được tìm thấy ở đây .

Dưới đây là ví dụ

def unpack_args(func):
    from functools import wraps
    @wraps(func)
    def wrapper(args):
        if isinstance(args, dict):
            return func(**args)
        else:
            return func(*args)
    return wrapper

@unpack_args
def func(x, y):
    return x + y

Sau đó, bạn có thể ánh xạ nó với các đối số được nén

np, xlist, ylist = 2, range(10), range(10)
pool = Pool(np)
res = pool.map(func, zip(xlist, ylist))
pool.close()
pool.join()

Tất nhiên, bạn luôn có thể sử dụng Pool.starmaptrong Python 3 (> = 3.3) như được đề cập trong các câu trả lời khác.


Kết quả không như mong đợi: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] Tôi mong đợi: [0,1,2,3,4,5,6,7,8, 9,1,2,3,4,5,6,7,8,9,10,2,3,4,5,6,7,8,9,10,11, ...
Tedo Vrbanec

@TedoVrbanec Kết quả chỉ nên là [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]. Nếu bạn muốn cái sau, bạn có thể sử dụng itertools.productthay vì zip.
Syrtis Major

4

Một cách khác là chuyển danh sách các danh sách sang thói quen một đối số:

import os
from multiprocessing import Pool

def task(args):
    print "PID =", os.getpid(), ", arg1 =", args[0], ", arg2 =", args[1]

pool = Pool()

pool.map(task, [
        [1,2],
        [3,4],
        [5,6],
        [7,8]
    ])

Người ta có thể xây dựng một danh sách các danh sách các đối số với phương thức yêu thích của một người.


Đây là một cách dễ dàng, nhưng bạn cần thay đổi các chức năng ban đầu của mình. Hơn nữa, đôi khi nhớ lại các chức năng của người khác mà không thể sửa đổi.
WeizhongTu

Tôi sẽ nói điều này với Python zen. Nên có một và chỉ một cách rõ ràng để làm điều đó. Nếu tình cờ bạn là tác giả của chức năng gọi, thì bạn nên sử dụng phương thức này, đối với các trường hợp khác, chúng ta có thể sử dụng phương thức của imotai.
nehem

Sự lựa chọn của tôi là sử dụng một tuple, và sau đó ngay lập tức mở khóa chúng như là điều đầu tiên trong dòng đầu tiên.
nehem

3

Đây là một cách khác để làm điều đó IMHO đơn giản và thanh lịch hơn bất kỳ câu trả lời nào khác được cung cấp.

Chương trình này có chức năng lấy hai tham số, in chúng ra và cũng in tổng:

import multiprocessing

def main():

    with multiprocessing.Pool(10) as pool:
        params = [ (2, 2), (3, 3), (4, 4) ]
        pool.starmap(printSum, params)
    # end with

# end function

def printSum(num1, num2):
    mySum = num1 + num2
    print('num1 = ' + str(num1) + ', num2 = ' + str(num2) + ', sum = ' + str(mySum))
# end function

if __name__ == '__main__':
    main()

đầu ra là:

num1 = 2, num2 = 2, sum = 4
num1 = 3, num2 = 3, sum = 6
num1 = 4, num2 = 4, sum = 8

Xem tài liệu python để biết thêm:

https://docs.python.org/3/l Library / multiprocessing.html # module-multiprocessing.pool

Đặc biệt hãy chắc chắn kiểm tra starmapchức năng.

Tôi đang sử dụng Python 3.6, tôi không chắc liệu nó có hoạt động với các phiên bản Python cũ hơn không

Tại sao không có một ví dụ rất đơn giản như thế này trong các tài liệu, tôi không chắc chắn.


2

Từ python 3.4.4, bạn có thể sử dụng Multiprocessing.get_context () để có được một đối tượng bối cảnh để sử dụng nhiều phương thức start:

import multiprocessing as mp

def foo(q, h, w):
    q.put(h + ' ' + w)
    print(h + ' ' + w)

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,'hello', 'world'))
    p.start()
    print(q.get())
    p.join()

Hoặc bạn chỉ cần thay thế

pool.map(harvester(text,case),case, 1)

bởi:

pool.apply_async(harvester(text,case),case, 1)

2

Có nhiều câu trả lời ở đây, nhưng dường như không có câu nào cung cấp mã tương thích Python 2/3 sẽ hoạt động trên mọi phiên bản. Nếu bạn muốn mã của mình chỉ hoạt động , thì mã này sẽ hoạt động cho cả phiên bản Python:

# For python 2/3 compatibility, define pool context manager
# to support the 'with' statement in Python 2
if sys.version_info[0] == 2:
    from contextlib import contextmanager
    @contextmanager
    def multiprocessing_context(*args, **kwargs):
        pool = multiprocessing.Pool(*args, **kwargs)
        yield pool
        pool.terminate()
else:
    multiprocessing_context = multiprocessing.Pool

Sau đó, bạn có thể sử dụng đa xử lý theo cách Python 3 thông thường, tuy nhiên bạn thích. Ví dụ:

def _function_to_run_for_each(x):
       return x.lower()
with multiprocessing_context(processes=3) as pool:
    results = pool.map(_function_to_run_for_each, ['Bob', 'Sue', 'Tim'])    print(results)

sẽ hoạt động trong Python 2 hoặc Python 3.


1

Trong tài liệu chính thức nói rằng nó chỉ hỗ trợ một đối số có thể lặp lại. Tôi thích sử dụng application_async trong những trường hợp như vậy. Trong trường hợp của bạn, tôi sẽ làm:

from multiprocessing import Process, Pool, Manager

text = "test"
def harvester(text, case, q = None):
 X = case[0]
 res = text+ str(X)
 if q:
  q.put(res)
 return res


def block_until(q, results_queue, until_counter=0):
 i = 0
 while i < until_counter:
  results_queue.put(q.get())
  i+=1

if __name__ == '__main__':
 pool = multiprocessing.Pool(processes=6)
 case = RAW_DATASET
 m = Manager()
 q = m.Queue()
 results_queue = m.Queue() # when it completes results will reside in this queue
 blocking_process = Process(block_until, (q, results_queue, len(case)))
 blocking_process.start()
 for c in case:
  try:
   res = pool.apply_async(harvester, (text, case, q = None))
   res.get(timeout=0.1)
  except:
   pass
 blocking_process.join()

1
text = "test"

def unpack(args):
    return args[0](*args[1:])

def harvester(text, case):
    X = case[0]
    text+ str(X)

if __name__ == '__main__':
    pool = multiprocessing.Pool(processes=6)
    case = RAW_DATASET
    # args is a list of tuples 
    # with the function to execute as the first item in each tuple
    args = [(harvester, text, c) for c in case]
    # doing it this way, we can pass any function
    # and we don't need to define a wrapper for each different function
    # if we need to use more than one
    pool.map(unpack, args)
    pool.close()
    pool.join()

1

Đây là một ví dụ về thói quen tôi sử dụng để truyền nhiều đối số cho hàm một đối số được sử dụng trong một ngã ba pool.imap :

from multiprocessing import Pool

# Wrapper of the function to map:
class makefun:
    def __init__(self, var2):
        self.var2 = var2
    def fun(self, i):
        var2 = self.var2
        return var1[i] + var2

# Couple of variables for the example:
var1 = [1, 2, 3, 5, 6, 7, 8]
var2 = [9, 10, 11, 12]

# Open the pool:
pool = Pool(processes=2)

# Wrapper loop
for j in range(len(var2)):
    # Obtain the function to map
    pool_fun = makefun(var2[j]).fun

    # Fork loop
    for i, value in enumerate(pool.imap(pool_fun, range(len(var1))), 0):
        print(var1[i], '+' ,var2[j], '=', value)

# Close the pool
pool.close()

-3

Đối với python2, bạn có thể sử dụng thủ thuật này

def fun(a,b):
    return a+b

pool = multiprocessing.Pool(processes=6)
b=233
pool.map(lambda x:fun(x,b),range(1000))

tại sao b = 233. đánh bại mục đích của câu hỏi
như - nếu
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.