পাইথন 3 এ সমবায়.ফিউচার বনাম মাল্টিপ্রসেসিং


148

পাইথন ৩.২ প্রবর্তন করেছে কনক্র্যান্ট ফিউচার , যা পুরানো থ্রেডিং এবং মাল্টিপ্রসেসিং মডিউলগুলির কিছু উন্নত সমন্বয় বলে মনে হয় ।

পুরানো মাল্টিপ্রসেসিং মডিউলটির উপরে সিপিইউ আবদ্ধ কাজের জন্য এটি ব্যবহার করার সুবিধা এবং অসুবিধাগুলি কী কী?

এই নিবন্ধটি তাদের সাথে কাজ করা আরও সহজ করার পরামর্শ দেয় - এটাই কি?

উত্তর:


145

আমি concurrent.futuresআরও "অ্যাডভান্সড" বলব না - এটি একাধিক সহজ ইন্টারফেস যা আপনি একাধিক থ্রেড বা একাধিক প্রক্রিয়া অন্তর্নিহিত সমান্তরালতা জিমিক হিসাবে ব্যবহার না করেই একইভাবে কাজ করে same

সুতরাং, কার্যত "সহজ ইন্টারফেস" সমস্ত উদাহরণ মতো একই ঘটনা ঘটে বিনিময় প্রথা জড়িত আছেন: এটা এত কম পাওয়া যাচ্ছে তা শুধু কারণ বড় অংশ একটি অগভীর লার্নিং কার্ভ আছে, করতে শেখা যাবে; তবে, কারণ এটি কম বিকল্প সরবরাহ করে, অবশেষে এটি আপনাকে হতাশ করতে পারে উপায়গুলি আরও ধনী ইন্টারফেসগুলি না করে।

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

সম্পাদনা: উদাহরণ

আপনি উল্লেখ করা নিবন্ধে এখানে চূড়ান্ত কোডটি দেখানো হয়েছে, তবে আমি এটিকে কার্যকর করার জন্য একটি আমদানি বিবৃতি যুক্ত করছি:

from concurrent.futures import ProcessPoolExecutor
def pool_factorizer_map(nums, nprocs):
    # Let the executor divide the work among processes by using 'map'.
    with ProcessPoolExecutor(max_workers=nprocs) as executor:
        return {num:factors for num, factors in
                                zip(nums,
                                    executor.map(factorize_naive, nums))}

multiprocessingপরিবর্তে ব্যবহার করে ঠিক একই জিনিস এখানে :

import multiprocessing as mp
def mp_factorizer_map(nums, nprocs):
    with mp.Pool(nprocs) as pool:
        return {num:factors for num, factors in
                                zip(nums,
                                    pool.map(factorize_naive, nums))}

দ্রষ্টব্য যে multiprocessing.Poolপাইথন ৩.৩-তে প্রসঙ্গ পরিচালক হিসাবে অবজেক্টগুলি ব্যবহার করার ক্ষমতা যুক্ত করা হয়েছিল।

কোনটির সাথে কাজ করা সহজ? LOL ;-) তারা মূলত অভিন্ন।

একটি পার্থক্য হ'ল Poolজিনিসগুলি করার বিভিন্ন উপায়কে সমর্থন করে যা আপনি শেখার বক্ররেখার উপরে উঠে না যাওয়া পর্যন্ত বুঝতে পারবেন না এটি কত সহজ হতে পারে।

আবার, এই সমস্ত বিভিন্ন উপায় একটি শক্তি এবং দুর্বলতা উভয়ই। এগুলি একটি শক্তি কারণ কিছু পরিস্থিতিতে নমনীয়তার প্রয়োজন হতে পারে। "করণীয় কেবলমাত্র একটি সুস্পষ্ট উপায়" কারণ এগুলি দুর্বলতা। কোনও প্রকল্প যেমন concurrent.futuresতার ন্যূনতম এপিআই ব্যবহার করা যায় তাতে কৃতজ্ঞ অভিনবত্বের অভাবে দীর্ঘমেয়াদে রক্ষণাবেক্ষণ করা সম্ভবত সহজতর হবে (যদি সম্ভব হয়) তবে এটি সম্ভবত স্টিক করা।


20
"স্পিডআপ পাওয়ার কোনও সুযোগ পাওয়ার জন্য আপনার একাধিক থ্রেডের পরিবর্তে একাধিক প্রক্রিয়া প্রয়োজন" খুব কঠোর। গতি যদি গুরুত্বপূর্ণ হয়; কোডটি ইতিমধ্যে একটি সি লাইব্রেরি ব্যবহার করতে পারে এবং তাই এটি জিআইএল যেমন, রেজেক্স, এলএক্সএমএল, নম্পী প্রকাশ করতে পারে।
jfs

4
@ জেফাসেবাস্টিয়ান, এটি যোগ করার জন্য ধন্যবাদ - সম্ভবত আমার " খাঁটি সিপিথনের অধীনে" কথা বলা উচিত ছিল , তবে আমি ভয় করি যে জিআইএল নিয়ে আলোচনা না করে এখানে সত্যকে ব্যাখ্যা করার মতো কোনও ছোট উপায় নেই।
টিম পিটার্স

2
এবং এটি উল্লেখযোগ্য যে দীর্ঘ আইও দিয়ে অপারেশন করার সময় থ্রেডগুলি বিশেষত দরকারী এবং পর্যাপ্ত হতে পারে।
কোটারফা

9
@ টিমপিটারগুলি কিছু উপায়ে ProcessPoolExecutorআসলে আরও বেশি বিকল্প রয়েছে Poolকারণ ProcessPoolExecutor.submitপ্রত্যাবর্তনের Futureউদাহরণগুলি বাতিল করার অনুমতি দেয় ( cancel), কোনটি ব্যতিক্রম উত্থাপিত হয়েছিল তা পরীক্ষা করে ( exception) এবং গতিশীলভাবে একটি কলব্যাক যোগ করার পরে ডেকে আনা হবে ( add_done_callback)। এই বৈশিষ্ট্যগুলির AsyncResultকোনওটিই প্রত্যাবর্তনের উদাহরণ সহ উপলভ্য নয় Pool.apply_async। অন্য কোন উপায়ে Poolকারণে আরও বিকল্প আছে initializer/ initargs, maxtasksperchildএবং contextমধ্যে Pool.__init__, এবং আরো অনেক পদ্ধতি দ্বারা উদ্ভাসিত Poolউদাহরণস্বরূপ।
সর্বাধিক

2
@ ম্যাক্স, নিশ্চিত, তবে মনে রাখবেন যে প্রশ্নটি ছিল না Pool, এটি মডিউলগুলির বিষয়ে ছিল। Poolযা আছে তার একটি ছোট্ট অংশ multiprocessingএবং এটি ডক্সে এতদূর নিচে রয়েছে যে এটি উপলব্ধি করতে লোকদের কিছুটা সময় লাগে multiprocessing। এই নির্দিষ্ট উত্তরটি কেন্দ্রীভূত হয়েছে Poolকারণ এটি ওপি ব্যবহারের সাথে লিঙ্কিত সমস্ত নিবন্ধ, এবং এটি cf"এর সাথে কাজ করা অনেক সহজ" কেবল নিবন্ধটি যা আলোচনা করেছিল সে সম্পর্কে সত্য নয়। তার পরেও যে, cfএর as_completed()খুব কুশলী হতে পারে।
টিম পিটার্স
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.