পাইথন মাল্টিপ্রসেসিং পুল.ম্যাপ একাধিক যুক্তির জন্য


532

পাইথন মাল্টিপ্রসেসিং লাইব্রেরিতে, পুল.ম্যাপের বৈকল্পিক রয়েছে যা একাধিক যুক্তি সমর্থন করে?

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
আমার অবাক করার বিষয়, আমি এটি partialকরতেও lambdaপারি না বা করতেও পারি না। আমি মনে করি এটি অদ্ভুত উপায়ে করতে হবে যা ফাংশনগুলি সাব-প্রসেসিসগুলিতে (মাধ্যমে pickle) পাস করা হয় ।
প্রেরক

10
@ সেন্ডারেল: এটি পাইথন ২.6 এ একটি বাগ, তবে এটি ২.7 হিসাবে ঠিক করা হয়েছে: bugs.python.org/issue5228
unutbu

1
কেবলমাত্র এর pool.map(harvester(text,case),case, 1) দ্বারা প্রতিস্থাপন করুন : pool.apply_async(harvester(text,case),case, 1)
টুং নগুইন

3
@ সির্তিস_মজোর, দয়া করে ওপি প্রশ্নগুলি সম্পাদনা করবেন না যা কার্যকরভাবে পূর্বে দেওয়া উত্তরগুলি আঁকায়। যোগ করার পদ্ধতি returnথেকে harvester()বেঠিক হচ্ছে পরিণত @senderie এর প্রতিক্রিয়া। যা ভবিষ্যতের পাঠকদের সহায়তা করে না।
রিক্যালসিন

1
আমি বলব সহজ সমাধান হ'ল সমস্ত আর্গগুলিকে একটি টিপলে প্যাক করা এবং এটি এক্সিকিউটিভ ফানকে আনপ্যাক করা। প্রক্রিয়াগুলির একটি পুল দ্বারা কার্যকর করা একটি ফানককে জটিল মাল্টিপল আরগগুলি প্রেরণের দরকার হওয়ার সময় আমি এটি করেছি।
এইচএস রাঠোর

উত্তর:


356

এর উত্তরটি সংস্করণ- এবং পরিস্থিতি-নির্ভর। পাইথনের সাম্প্রতিক সংস্করণের সর্বাধিক সাধারণ উত্তর (৩.৩ থেকে) প্রথমে নীচে জেএফ সেবাস্তিয়ান বর্ণনা করেছেন । 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তবে কেবল পাইথন ২.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()(অজগর ২.
মিউন

1
@ মুন, ভাল ক্যাচ মনে হচ্ছে Poolবস্তু পাইথন 3.3 পর্যন্ত প্রেক্ষাপটে পরিচালকদের হয় না। আমি একটি সাধারণ মোড়ক ফাংশন যুক্ত করেছি যা একটি Poolপ্রসঙ্গ পরিচালককে ফিরে দেয় ।
প্রেরক

499

পুল.ম্যাপের বৈকল্পিক রয়েছে যা একাধিক যুক্তি সমর্থন করে?

পাইথন ৩.৩ এর মধ্যে রয়েছে 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()ব্যবহৃত হয় তা লক্ষ্য করুন।

@ ইউন্টবু দ্বারা উল্লিখিত বাগের কারণে আপনি functools.partial()পাইথন ২.6 এ ব্যবহার করতে পারবেন না বা অনুরূপ ক্ষমতা রাখতে পারবেন , তাই সাধারণ মোড়কের কাজটি func_star()স্পষ্টভাবে সংজ্ঞায়িত করা উচিত। প্রস্তাবিত কর্মশালাও দেখুন ।uptimebox


1
এফ .: আপনি এর স্বাক্ষরে যুক্তি tuple প্যাকমুক্ত করতে func_starভালো: def func_star((a, b))। অবশ্যই, এটি কেবল একটি নির্দিষ্ট সংখ্যক যুক্তিগুলির জন্যই কাজ করে, তবে এটি যদি তার একমাত্র কেস হয় তবে এটি আরও পাঠযোগ্য।
বুজরন পোল্লেক্স 21

1
@ Space_C0wb0y: f((a,b))সিনট্যাক্স পিয়ার 3 কে অবচয় এবং সরানো হয়েছে। এবং এটি এখানে অপ্রয়োজনীয়।
jfs

সম্ভবত আরও অজগর: func = lambda x: func(*x)একটি মোড়ক ফাংশন সংজ্ঞায়নের পরিবর্তে
ডিলাম

1
@ zthomas.nc এই প্রশ্নটি মাল্টিপ্রসেসিং পুল.ম্যাপের জন্য একাধিক যুক্তি সমর্থন করার বিষয়ে। যদি মাল্টিপ্রসেসিংয়ের মাধ্যমে পৃথক পাইথন প্রক্রিয়াতে ফাংশনের পরিবর্তে কোনও পদ্ধতিতে কল করতে হয় তা জানতে চাইলে একটি পৃথক প্রশ্ন জিজ্ঞাসা করুন (অন্য সব কিছু যদি ব্যর্থ হয় তবে আপনি সর্বদা একটি বিশ্বব্যাপী ফাংশন তৈরি করতে পারেন যা পদ্ধতিটির কলকে func_star()উপরের মতো
অনুরূপভাবে আবৃত করে

1
আমি সেখানে ছিল ইচ্ছুক starstarmap
Константин Ван

140

আমি মনে করি নীচে আরও ভাল হবে

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কোনও তালিকায় রাখতে চান তবে আপনি এটি কীভাবে ব্যবহার করবেন ?
বিবেক সুব্রমনিয়ান

@ আহমদ আমার পছন্দ হয়েছে এটি কেমন, কারণ যখনই প্যারামিটারের সংখ্যা সঠিক না হয় তখন আইএমএইচও পদ্ধতি কলটি ব্যর্থ হয়।
মাইকেল ডারনার

56

সাথে পাইথন ৩.৩+ ব্যবহার করা হচ্ছে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
এটি ২০১১ সালের @ জেএফএসবেস্টিয়ান থেকে প্রাপ্ত হিসাবে প্রায় 60০ টি ভোট সহ একটি নিকট সঠিক হুবহু জবাব।
মাইক ম্যাকার্নস

29
না all সবার আগে এটি প্রচুর অপ্রয়োজনীয় জিনিস সরিয়ে ফেলে এবং স্পষ্টভাবে বলে যে এটি অজগর 3.3+ এর জন্য এবং এটি একটি সহজ এবং পরিষ্কার উত্তর খুঁজছেন এমন প্রাথমিকের জন্যই। একজন শিক্ষানবিস হিসাবে আমি এটি সেভাবে খুঁজে পেতে কিছুটা সময় নিয়েছিলাম (হ্যাঁ জেএফএসবেস্টিয়ানস পোস্টগুলির সাথে) এবং এই কারণেই আমি আমার অন্য লেখকদের সাহায্য করার জন্য আমার পোস্টটি লিখেছিলাম, কারণ তার পোস্টটি কেবল "স্টারম্যাপ" আছে তবে এটি ব্যাখ্যা করেনি - এটি আমার পোস্টের ইচ্ছাই তাই। সুতরাং দুটি ডাউনভোট দিয়ে আমাকে ধর্ষণ করার কোনও কারণ নেই।
ব্যবহারকারী 136036

২০১১ সালে পাইথন ৩.৩+ তে "+" ছিল না ... তাই স্পষ্টতই।
মাইক ম্যাকার্নস

27

মধ্যে itertools সম্পর্কে শিখেছি রয়ে জেএফ সেবাস্টিয়ান উত্তর আমি এটি একটি ধাপ গ্রহণ করা এবং একটি লিখতে করার সিদ্ধান্ত নিয়েছে parmapপ্যাকেজ যে সম্পর্কে parallelization, নৈবেদ্য যত্ন নেয় mapএবং starmapপাইথন-2.7 এবং পাইথন-3.2 (এবং পরে আরো) যে গ্রহণ করতে পারেন উপর ফাংশন কোন সংখ্যা অবস্থানগত আর্গুমেন্ট ।

স্থাপন

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)

আমি পিআইপিআই এবং গিথুব সংগ্রহস্থলে পার্ম্যাপটি আপলোড করেছি ।

উদাহরণ হিসাবে, প্রশ্নের উত্তর নিম্নরূপ দেওয়া যেতে পারে:

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
ঝরঝরে এবং মার্জিত।
Prav001

1
আমি বুঝতে পারি না কেন সর্বোত্তম উত্তর খুঁজতে আমাকে এখানে সমস্ত দিকে স্ক্রোল করতে হবে।
তোতি

11

সেখানে multiprocessingবলা প্যাথোগুলির একটি কাঁটা রয়েছে ( দ্রষ্টব্য: গিথুব সংস্করণটি ব্যবহার করুন ) যার দরকার নেই starmap- মানচিত্রের ফাইটিংগুলি পাইথনের মানচিত্রের জন্য এপিআইকে মিরর দেয়, সুতরাং মানচিত্রটি একাধিক যুক্তি নিতে পারে। সঙ্গেpathos আপনি __main__ব্লকে আটকে না গিয়ে সাধারণভাবে দোভাষীটিতে একাধিক প্রসেসিংও করতে পারেন । কিছু হালকা হালকা আপডেট করার পরে - প্যাথোজগুলি একটি মুক্তির জন্য প্রযোজ্য - বেশিরভাগই পাইথন 3.x তে রূপান্তর ion

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

আমি লক্ষ করতে চাই যে এটি মূল প্রশ্নের কাঠামোটিকে সম্বোধন করে না। [[1,2,3], [4,5,6]] স্টারম্যাপের সাথে [পাউ (1,2,3), পাও (4,5,6)] আনপ্যাক করবে, [পাও (1,4) না , পাউ (2,5), পাউ (3, 6)]। আপনার ফাংশনে যে ইনপুটগুলি দেওয়া হচ্ছে তার উপর যদি আপনার ভাল নিয়ন্ত্রণ না থাকে তবে আপনাকে প্রথমে সেগুলি পুনর্গঠন করতে হবে।
স্কট 16

@ স্কট: আহ, আমি লক্ষ্য করেছি না ... 5 বছর আগে। আমি একটি ছোট আপডেট করব। ধন্যবাদ।
মাইক ম্যাকার্নস 17

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

পাইথন 2 এর জন্য আরও ভাল সমাধান:

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

[] আউট:

[৩, ৫,]]


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, ...
টেডো ভ্রাবনেক

@ টেডোবার্বানেকের ফলাফলগুলি কেবল [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]
    ])

যে কেউ নিজের পছন্দের পদ্ধতির সাহায্যে যুক্তিগুলির তালিকা তৈরি করতে পারে One


এটি একটি সহজ উপায়, তবে আপনাকে আপনার মূল ফাংশনগুলি পরিবর্তন করতে হবে। আরও কি, কিছু সময় অন্যের কার্যাবলি স্মরণ করুন যা সংশোধন করা যায় না।
ওয়েইজহংটু

আমি পাইথন জেনকে এই কাঠিগুলি বলব। এটি করার একটি এবং একমাত্র সুস্পষ্ট উপায় থাকতে হবে। যদি সুযোগক্রমে আপনি কলিং ফাংশনের লেখক হন তবে আপনার এই পদ্ধতিটি ব্যবহার করা উচিত, অন্যান্য ক্ষেত্রে আমরা ইমোটাইয়ের পদ্ধতিটি ব্যবহার করতে পারি।
নেহেম 1

আমার পছন্দটি হল একটি টিউপল ব্যবহার করা এবং তারপরে তাত্ক্ষণিকভাবে প্রথম লাইনে প্রথম জিনিস হিসাবে এটি আন-আপ করুন।
নেহেম

3

এটি করার আরেকটি উপায় এখানে দেওয়া যে অন্য উত্তরগুলির চেয়ে আইএমএইচও আরও সহজ এবং মার্জিত।

এই প্রোগ্রামটিতে একটি ফাংশন রয়েছে যা দুটি পরামিতি নেয়, তাদের মুদ্রণ করে এবং যোগফলটিও মুদ্রণ করে:

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ফাংশনটি পরীক্ষা করে দেখুন be

আমি পাইথন ৩.6 ব্যবহার করছি, আমি নিশ্চিত নই যে এটি পুরানো পাইথনের সংস্করণগুলির সাথে কাজ করবে কিনা

ডক্সে কেন এর মতো খুব সোজা-ফরোয়ার্ডের উদাহরণ নেই, আমি নিশ্চিত নই।


2

পাইথন ৩.৪.৪ থেকে আপনি একাধিক প্রারম্ভিক পদ্ধতিগুলি ব্যবহার করার জন্য একটি প্রসঙ্গ অবজেক্টটি পেতে মাল্টিপ্রসেসিং.জেট_কন্টেক্সট () ব্যবহার করতে পারেন:

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

অফিসিয়াল ডকুমেন্টেশনে বলা হয়েছে যে এটি কেবল একটি পুনরাবৃত্ত যুক্তি সমর্থন করে। আমি এই জাতীয় ক্ষেত্রে প্রয়োগ_সিন্যাস ব্যবহার করতে চাই। আপনার ক্ষেত্রে আমি করব:

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

পাইথন 2 এর জন্য, আপনি এই কৌশলটি ব্যবহার করতে পারেন

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

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

কেন খ = 233। প্রশ্নের উদ্দেশ্যকে পরাস্ত করে
যেমন - যদি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.