कई तर्कों के लिए पायथन मल्टीप्रोसेसिंग पूल.मैप


533

पायथन मल्टीप्रोसेसिंग लाइब्रेरी में, पूल का एक संस्करण है ।मैप जो कई तर्कों का समर्थन करता है?

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
अपने आश्चर्य के लिए, मैं partiallambdaतो ऐसा कर सकता था और न ही कर सकता था। मुझे लगता है कि यह अजीब तरीके से करना है कि फ़ंक्शन उपप्रोसेस (के माध्यम से pickle) में पारित हो जाते हैं ।
प्रेषक

10
@ सादर: यह पायथन 2.6 में एक बग है, लेकिन इसे 2.7 के रूप में तय किया गया है: Bugs.python.org/issue5228
unutbu

1
बस pool.map(harvester(text,case),case, 1) द्वारा प्रतिस्थापित : pool.apply_async(harvester(text,case),case, 1)
तुंग गुयेन

3
@Syrtis_Major, कृपया ओपी प्रश्नों को संपादित न करें जो पहले दिए गए उत्तर को प्रभावी ढंग से तिरछा करते हैं। जोड़ने returnके लिए harvester()गलत किया जा रहा है में बदल गया @senderie की प्रतिक्रिया। यह भविष्य के पाठकों की मदद नहीं करता है।
रिटिकलिन

1
मैं कहूंगा कि आसान उपाय यह होगा कि सभी आर्गनों को एक टुपल में पैक किया जाए और इसे निष्पादित फंक में अनपैक किया जाए। मैंने ऐसा तब किया, जब मुझे प्रक्रियाओं के एक पूल द्वारा निष्पादित किए जा रहे फंक के लिए जटिल कई आर्गन भेजने की आवश्यकता थी।
एचएस राठौर

जवाबों:


357

इसका उत्तर संस्करण है- और स्थिति-निर्भर। पायथन के हाल के संस्करणों के लिए सबसे सामान्य उत्तर (3.3 के बाद से) पहले जेएफ सेबेस्टियन द्वारा नीचे वर्णित किया गया था । 1 यह Pool.starmapविधि का उपयोग करता है , जो तर्क ट्यूपल्स के एक क्रम को स्वीकार करता है। यह तब स्वचालित रूप से प्रत्येक टपल से तर्कों को हटा देता है और उन्हें दिए गए फ़ंक्शन में भेज देता है:

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', ...

पायथन के पुराने संस्करणों के लिए, आपको तर्कों को स्पष्ट रूप से अनपैक करने के लिए एक सहायक फ़ंक्शन लिखना होगा। यदि आप उपयोग करना चाहते हैं with, तो आपको Poolसंदर्भ प्रबंधक में बदलने के लिए एक आवरण लिखना होगा । ( यह इंगित करने के लिए म्यूऑन के लिए धन्यवाद ।)

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', ...

सरल मामलों में, एक निश्चित दूसरे तर्क के साथ, आप भी उपयोग कर सकते हैं partial, लेकिन केवल पायथन 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. इसका अधिकांश हिस्सा उनके जवाब से प्रेरित था, जिसे शायद इसके बजाय स्वीकार किया जाना चाहिए था। लेकिन चूंकि यह शीर्ष पर अटका हुआ है, इसलिए भविष्य के पाठकों के लिए इसमें सुधार करना सबसे अच्छा लग रहा था।


मुझे ऐसा लगता है कि इस मामले में RAW_DATASET एक वैश्विक चर होना चाहिए? जबकि मैं चाहता हूं कि आंशिक_हेरवेस्टर हारवेस्टर () की हर कॉल में मामले के मूल्य को बदल दे। कैसे प्राप्त करें?
xgdgsc

यहां सबसे महत्वपूर्ण बात =RAW_DATASETडिफ़ॉल्ट मान असाइन करना है case। अन्यथा pool.mapकई तर्कों के बारे में भ्रमित करेगा।
इमर्सन जू

1
मैं भ्रमित हूं, textआपके उदाहरण में चर का क्या हुआ ? क्यों RAW_DATASETदो बार प्रतीत होता है। मुझे लगता है कि आपके पास एक टाइपो हो सकता है?
डेव

यकीन नहीं है कि with .. as .. मुझे क्यों देता है AttributeError: __exit__, लेकिन ठीक काम करता है अगर मैं फोन करता हूं pool = Pool();तो मैन्युअल रूप से बंद करें pool.close()(python2.7)
muon

1
@ मून, अच्छी पकड़। ऐसा प्रतीत होता है Poolकि पायथन 3.3 तक ऑब्जेक्ट संदर्भ प्रबंधक नहीं बनते हैं। मैंने एक साधारण रैपर फ़ंक्शन जोड़ा है जो एक Poolसंदर्भ प्रबंधक देता है ।
प्रेषक

499

वहाँ पूल का एक संस्करण है। जो कई तर्कों का समर्थन करते हैं?

पायथन 3.3 में pool.starmap()विधि शामिल है :

#!/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()

पुराने संस्करणों के लिए:

#!/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()

उत्पादन

1 1
2 1
3 1

ध्यान दें कि कैसे itertools.izip()और itertools.repeat()यहाँ उपयोग किया जाता है।

@Unutbu द्वारा बताए गए बग के कारण आप functools.partial()पायथन 2.6 पर या इसी तरह की क्षमताओं का उपयोग नहीं कर सकते हैं , इसलिए सरल आवरण फ़ंक्शन func_star()को स्पष्ट रूप से परिभाषित किया जाना चाहिए। द्वारा सुझाया गया वर्कअराउंड भी देखें ।uptimebox


1
एफ .: आप func_starइस तरह से हस्ताक्षर में टपल को अनपैक कर सकते हैं def func_star((a, b)):। बेशक, यह केवल निश्चित संख्या में तर्कों के लिए काम करता है, लेकिन अगर केवल यही मामला है, तो यह अधिक पठनीय है।
ब्योर्न पोलेक्स

1
@ Space_C0wb0y: f((a,b))वाक्यविन्यास को हटाकर py3k में हटा दिया जाता है। और यह यहाँ अनावश्यक है।
jfs

शायद अधिक पायथोनिक: func = lambda x: func(*x)एक आवरण समारोह को परिभाषित करने के बजाय
डायलाम

1
@ zthomas.nc यह सवाल है कि मल्टीप्रोसेसिंग पूल के लिए कई तर्कों का समर्थन कैसे किया जाए। यदि जानना चाहते हैं कि मल्टीप्रोसेसिंग के माध्यम से एक अलग पायथन प्रक्रिया में एक फ़ंक्शन के बजाय एक विधि को कैसे कॉल किया जाए तो एक अलग प्रश्न पूछें (यदि बाकी सभी विफल रहता है, तो आप हमेशा एक वैश्विक फ़ंक्शन बना सकते हैं जो func_star()ऊपर दिए गए विधि कॉल को लपेटता है)
jfs

1
काश वहाँ थे starstarmap
Константин Ван

141

मुझे लगता है कि नीचे बेहतर होगा

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

उत्पादन

[3, 5, 7]

16
सबसे आसान समाधान। एक छोटा अनुकूलन है; रैपर फ़ंक्शन को हटा दें और argsसीधे अनपैक करें add, यह किसी भी तर्क के लिए काम करता है:def add(args): (x,y) = args
अहमद

1
आप lambdaपरिभाषित करने के बजाय एक फ़ंक्शन का उपयोग भी कर सकते हैंmulti_run_wrapper(..)
आंद्रे होल्ज़नर

2
हम्म ... वास्तव में, एक lambdaकाम नहीं करता है क्योंकि pool.map(..)दिए गए फ़ंक्शन को अचार करने की कोशिश करता है
आंद्रे होल्ज़नर

यदि आप addकिसी सूची के परिणाम को संग्रहीत करना चाहते हैं तो आप इसका उपयोग कैसे करते हैं ?
विवेक सुब्रमण्यन

@ मुझे यह पसंद है कि यह कैसा है, क्योंकि जब भी पैरामीटर की संख्या सही नहीं होती है तो IMHO विधि कॉल विफल हो जाती है।
माइकल डॉर्नर

56

के साथ Python 3.3+ का उपयोग करनाpool.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()

परिणाम:

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

यदि आपको पसंद हो तो आप और भी तर्क दे सकते हैं: zip(a,b,c,d,e)

यदि आप एक निरंतर मूल्य को एक तर्क के रूप में पारित करना चाहते हैं जिसे आपको उपयोग करना है import itertoolsऔर फिर zip(itertools.repeat(constant), a)उदाहरण के लिए।


2
यह 2011 में @JFSebastian (60+ वोटों के साथ) के रूप में एक सटीक सटीक उत्तर है।
माइक मैककर्नस

29
नहीं। सबसे पहले इसने बहुत सारे अनावश्यक सामानों को हटा दिया और स्पष्ट रूप से कहा कि यह अजगर 3.3+ के लिए है और शुरुआती लोगों के लिए अभिप्रेत है जो एक सरल और स्वच्छ उत्तर की तलाश में हैं। एक शुरुआत के रूप में खुद को इस तरह से पता लगाने में कुछ समय लगा (हाँ, JFSebastians पोस्ट के साथ) और इसी कारण मैंने अन्य शुरुआती लोगों की मदद करने के लिए अपनी पोस्ट लिखी, क्योंकि उनके पोस्ट में बस इतना कहा गया था कि "स्टार्मैप है" लेकिन इसे समझाया नहीं - मेरी पोस्ट का इरादा है। इसलिए मुझे दो डाउनवोट के साथ काटने का कोई कारण नहीं है।
user136036

2011 में, अजगर 3.3 + में कोई "+" नहीं था ... तो जाहिर है।
माइक मैककर्न्स

27

जेएफ सेबेस्टियन उत्तर में इटर्टूल के बारे में जानने के बाद मैंने इसे एक कदम आगे बढ़ाने का फैसला किया और एक parmapपैकेज लिखा जो कि पायथन-2.7 और पाइथन-3.2 (और बाद में भी) पर किसी भी संख्या में ले जा सकने वाले समानांतरकरण, पेशकश mapऔर starmapकार्यों के बारे में ध्यान रखता है। स्थिति में तर्क दे सकते हैं। ।

स्थापना

pip install parmap

कैसे समानांतर करें:

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)

मैंने पेमप को PyPI और एक गिथब रिपॉजिटरी में अपलोड किया है

एक उदाहरण के रूप में, प्रश्न का उत्तर निम्नानुसार दिया जा सकता है:

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)

19

# "कई तर्क कैसे लें"।

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
नीट और सुरुचिपूर्ण।
20

1
मुझे समझ में नहीं आ रहा है कि मुझे सबसे अच्छा उत्तर खोजने के लिए यहाँ पर सभी तरह से स्क्रॉल क्यों करना है।
टोटी

11

पथोmultiprocessing नामक एक कांटा है ( ध्यान दें: गीथब पर संस्करण का उपयोग करें ) जिसकी आवश्यकता नहीं है starmap- मानचित्र कार्य अजगर के नक्शे के लिए एपीआई को दर्पण करता है, इस प्रकार नक्शा कई तर्क ले सकता है। के साथ pathos, आप आम तौर पर इंटरप्रेटर में मल्टीप्रोसेसिंग भी कर सकते हैं, __main__ब्लॉक में फंसने के बजाय । पैथोस एक रिलीज के कारण होता है, कुछ हल्के अपडेट के बाद - ज्यादातर अजगर 3.x में परिवर्तित होता है।

  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]

pathosकई तरीके हैं जिनसे आप सटीक व्यवहार प्राप्त कर सकते हैं 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]
>>> 

मैं यह नोट करना चाहता हूं कि यह मूल प्रश्न में संरचना को संबोधित नहीं करता है। [[१,२,३], [४,५,६]] स्टैपैप से [पाव (१,२,३), पाव (४,५,६)] अनपैक होगा, न कि [पाव (१,४)] , पॉव (2,5), पाउ (3, 6)]। यदि आपके पास अपने फ़ंक्शन को पास किए जा रहे इनपुट पर अच्छा नियंत्रण नहीं है, तो आपको उन्हें पहले पुनर्गठन करने की आवश्यकता हो सकती है।
स्कॉट

@ स्कॉट: आह, मैंने देखा नहीं है कि ... 5 साल पहले। मैं एक छोटा सा अपडेट करूंगा। धन्यवाद।
माइक मैककर्न्स

8

आप निम्न दो कार्यों का उपयोग कर सकते हैं ताकि प्रत्येक नए फ़ंक्शन के लिए एक आवरण लिखने से बचें:

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

functionतर्कों की सूची के साथ फ़ंक्शन का उपयोग करें arg_0, arg_1और arg_2निम्नानुसार है:

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

8

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))])

२ ३ ४

१ २ ३

0 1 2

बाहर[]:

[३, ५, 7]


7

एक और सरल विकल्प यह है कि आप अपने कार्य मापदंडों को एक ट्यूपल में लपेटें और फिर उन मापदंडों को लपेटें जिन्हें ट्यूपल्स में पारित किया जाना चाहिए। डेटा के बड़े टुकड़ों से निपटने के दौरान यह आदर्श नहीं है। मेरा मानना ​​है कि यह प्रत्येक टपल के लिए प्रतियां बनायेगा।

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()

कुछ यादृच्छिक क्रम में आउटपुट देता है:

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]

वास्तव में, यह अभी भी बेहतर तरीके की तलाश में है :(
फैबियो डायस

6

एक बेहतर तरीका हाथ से आवरण समारोह लिखने के बजाय डेकोरेटर का उपयोग करना है। खासकर जब आपके पास मैप करने के लिए बहुत सारे कार्य हैं, तो डेकोरेटर हर फ़ंक्शन के लिए आवरण लिखने से बचकर अपना समय बचाएगा। आमतौर पर एक सजाया गया कार्य पिक करने योग्य नहीं होता है, हालाँकि हम इसका उपयोग कर सकते हैं functools। यहां और अधिक असंतोष पाए जा सकते हैं

यहाँ उदाहरण है

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

फिर आप इसे ज़िपित तर्कों के साथ मैप कर सकते हैं

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

बेशक, आप हमेशा Pool.starmapपायथन 3 (> = 3.3) में उपयोग कर सकते हैं जैसा कि अन्य उत्तरों में बताया गया है।


परिणाम अपेक्षित नहीं हैं: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] मैं उम्मीद करूंगा: [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 परिणाम सिर्फ [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] होना चाहिए। यदि आप बाद में चाहते हैं, तो आप itertools.productइसके बजाय उपयोग कर सकते हैं zip
सिरिटिस मेजर

4

एक और तरीका यह है कि सूची की सूची को एक-तर्क दिनचर्या में पारित किया जाए:

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]
    ])

व्यक्ति की पसंदीदा पद्धति के साथ तर्कों की एक सूची सूची का निर्माण कर सकता है।


यह एक आसान तरीका है, लेकिन आपको अपने मूल कार्यों को बदलने की आवश्यकता है। क्या अधिक है, कुछ समय दूसरों के कार्यों को याद करते हैं जिन्हें संशोधित नहीं किया जा सकता है।
WeizhongTu

मैं कहूंगा कि यह पायथन ज़ेन से चिपका है। ऐसा करने के लिए एक और केवल एक स्पष्ट तरीका होना चाहिए। यदि संयोग से आप कॉलिंग फ़ंक्शन के लेखक हैं, तो आपको इस विधि का उपयोग करना चाहिए, अन्य मामलों के लिए हम imotai की विधि का उपयोग कर सकते हैं।
नेहेम

मेरी पसंद एक टपल का उपयोग करना है, और फिर तुरंत उन्हें पहली पंक्ति में पहली चीज के रूप में खोल देना है।
नेहेम

3

यह करने का एक और तरीका है कि IMHO प्रदान किए गए अन्य उत्तरों की तुलना में अधिक सरल और सुरुचिपूर्ण है।

इस कार्यक्रम का एक कार्य है जो दो मापदंडों को लेता है, उन्हें प्रिंट करता है और योग को भी प्रिंट करता है:

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()

आउटपुट है:

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

अधिक जानकारी के लिए अजगर डॉक्स देखें:

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

विशेष रूप से starmapफ़ंक्शन की जांच करना सुनिश्चित करें ।

मैं पायथन 3.6 का उपयोग कर रहा हूं, मुझे यकीन नहीं है कि यह पुराने पायथन संस्करणों के साथ काम करेगा

डॉक्स में इस तरह का बहुत सीधा-सीधा उदाहरण क्यों नहीं है, मुझे यकीन नहीं है।


2

अजगर 3.4.4 से, आप कई तरीकों का उपयोग करने के लिए एक संदर्भ वस्तु प्राप्त करने के लिए multiprocessing.get_context () का उपयोग कर सकते हैं:

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()

या आप बस प्रतिस्थापित करें

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

द्वारा:

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

2

यहाँ कई उत्तर हैं, लेकिन कोई भी 2/3 संगत कोड पायथन प्रदान नहीं करता है जो किसी भी संस्करण पर काम करेगा। यदि आप अपना कोड सिर्फ काम करना चाहते हैं , तो यह पायथन संस्करण के लिए काम करेगा:

# 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

उसके बाद, आप नियमित पाइथन 3 तरीके से मल्टीप्रोसेसिंग का उपयोग कर सकते हैं, हालांकि आपको पसंद है। उदाहरण के लिए:

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)

पायथन 2 या पायथन 3 में काम करेगा।


1

आधिकारिक दस्तावेज में कहा गया है कि यह केवल एक पुनरावृत्त तर्क का समर्थन करता है। मैं ऐसे मामलों में apply_async का उपयोग करना पसंद करता हूं। आपके मामले में मैं करूंगा:

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

यह दिनचर्या मैं उपयोग एक एक तर्क एक में इस्तेमाल किया कार्य करने के लिए कई तर्क पारित करने के लिए का एक उदाहरण है 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

python2 के लिए, आप इस ट्रिक का उपयोग कर सकते हैं

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

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

क्यों बी = 233। प्रश्न के उद्देश्य को पराजित करता है
जैसे कि -
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.