পাইথন মাল্টিপ্রসেসিং মডিউলটির জয়েন্ট () পদ্ধতি কী করছে?


110

পাইথন মাল্টিপ্রসেসিং (একটি পিএমওটডাব্লু নিবন্ধ থেকে ) সম্পর্কে শিখছি এবং join()পদ্ধতিটি ঠিক কী করছে তা সম্পর্কে কিছু ব্যাখ্যা পছন্দ করবে ।

২০০৮ সালের পুরানো টিউটোরিয়ালে এটি বর্ণিত হয়েছে যে p.join()নীচের কোডটিতে কল ছাড়াই "শিশু প্রক্রিয়াটি অলস বসে থাকবে এবং শেষ হবে না, একটি জম্বি হয়ে উঠবে আপনাকে অবশ্যই ম্যানুয়ালি হত্যা করতে হবে"।

from multiprocessing import Process

def say_hello(name='world'):
    print "Hello, %s" % name

p = Process(target=say_hello)
p.start()
p.join()

আমি পরীক্ষার PIDপাশাপাশি একটি মুদ্রণযন্ত্র যুক্ত করেছি time.sleepএবং যতদূর আমি বলতে পারি, প্রক্রিয়াটি নিজে থেকেই সমাপ্ত হয়:

from multiprocessing import Process
import sys
import time

def say_hello(name='world'):
    print "Hello, %s" % name
    print 'Starting:', p.name, p.pid
    sys.stdout.flush()
    print 'Exiting :', p.name, p.pid
    sys.stdout.flush()
    time.sleep(20)

p = Process(target=say_hello)
p.start()
# no p.join()

20 সেকেন্ডের মধ্যে:

936 ttys000    0:00.05 /Library/Frameworks/Python.framework/Versions/2.7/Reso
938 ttys000    0:00.00 /Library/Frameworks/Python.framework/Versions/2.7/Reso
947 ttys001    0:00.13 -bash

20 সেকেন্ড পরে:

947 ttys001    0:00.13 -bash

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

পদ্ধতিটির নাম সম্পর্কেও আমি ভাবছি। .join()পদ্ধতিটি কি এখানে কিছুকে মনযোগ দিচ্ছে ? এটি কি কোনও প্রক্রিয়াটি শেষ হওয়ার সাথে সাথে যুক্ত করে দিচ্ছে? অথবা এটি পাইথনের নেটিভ .join()পদ্ধতিতে কেবল একটি নাম ভাগ করে ?


2
যতদূর আমি জানি, এটি মূল থ্রেড ধারণ করে এবং শিশু প্রক্রিয়াটি সম্পূর্ণ হওয়ার জন্য অপেক্ষা করে এবং তারপরে মূল থ্রেডে সংস্থানগুলি ফিরে পেতে, বেশিরভাগ ক্ষেত্রে পরিষ্কার প্রস্থান হয়।
অভিষেকগারগ

আহ যে বোঝায়। সুতরাং এটি প্রকৃতপক্ষে CPU, Memory resourcesপিতামাতার প্রক্রিয়া থেকে আলাদা হচ্ছে, তারপরে joinসন্তানের প্রক্রিয়াটি শেষ হয়ে আবার ফিরে এডি হবে?
মাইকিএলএল

হ্যাঁ, এটিই করছে। সুতরাং, আপনি যদি তাদের সাথে ফিরে না যান, শিশু প্রক্রিয়াটি শেষ হয়ে গেলে এটি কেবলমাত্র একটি অবসন্ন বা মৃত প্রক্রিয়া হিসাবে মিথ্যা
অভিষেকার্গ

@ অভিষেকগার্গ এটি সত্য নয়। প্রধান প্রক্রিয়াটি সম্পূর্ণ হলে শিশু প্রক্রিয়াগুলি স্পষ্টভাবে যোগদান করবে।
ড্যানো

@ এডানো, আমি অজগরও শিখছি এবং আমি আমার পরীক্ষাগুলিতে যা পেয়েছি তা কেবল ভাগ করে নিয়েছি, আমার পরীক্ষাগুলিতে আমার কোনও শেষ না হওয়া মূল প্রক্রিয়া ছিল যাতে সম্ভবত আমি কেন এই শিশু প্রক্রিয়াগুলিকে অবনমিত বলে দেখি।
অভিষেকগারগ

উত্তর:


125

join()পদ্ধতি, যখন সঙ্গে ব্যবহার threadingবা multiprocessing, এর সাথে সম্পর্কিত নয় str.join()- এটা আসলে একসঙ্গে কিছু concatenating না। বরং, এর অর্থ কেবল "এই [থ্রেড / প্রক্রিয়া] শেষ হওয়ার জন্য অপেক্ষা করুন"। নামটি joinব্যবহৃত হয় কারণ multiprocessingমডিউলটির এপিআই বোঝানো হয়েছে threadingমডিউলটির এপিআই-র অনুরূপ , এবং threadingমডিউলটি joinতার Threadঅবজেক্টের জন্য ব্যবহার করে । join"থ্রেডটি সম্পূর্ণ হওয়ার অপেক্ষা করুন" অর্থ এই শব্দটি ব্যবহার করা অনেকগুলি প্রোগ্রামিং ভাষায় প্রচলিত, তাই পাইথন এটি কেবল এটি গ্রহণ করে।

এখন, আপনি কলটির সাথে এবং না ছাড়াই 20 সেকেন্ড বিলম্বের join()কারণটি ডিফল্টরূপে, যখন প্রধান প্রক্রিয়াটি প্রস্থান করার জন্য প্রস্তুত থাকে, তখন এটি স্পষ্টভাবে join()সমস্ত চলমান multiprocessing.Processদৃষ্টান্তগুলিতে কল করবে । এটি multiprocessingডক্সে যেমনটি হওয়া উচিত তেমন স্পষ্টভাবে বলা হয়নি তবে প্রোগ্রামিং গাইডলাইনস বিভাগে এটি উল্লেখ করা হয়েছে :

এও মনে রাখবেন যে নন-ডিমনিক প্রক্রিয়াগুলি স্বয়ংক্রিয়ভাবে যোগদান করবে।

প্রক্রিয়া শুরু করার পূর্বে daemonপতাকাটি সেট করে আপনি এই আচরণটি ওভাররাইড করতে পারেন :ProcessTrue

p = Process(target=say_hello)
p.daemon = True
p.start()
# Both parent and child will exit here, since the main process has completed.

যদি আপনি এটি করেন তবে মূল প্রক্রিয়াটি শেষ হওয়ার সাথে সাথে শিশু প্রক্রিয়াটি সমাপ্ত হবে :

অপদেবতা

প্রক্রিয়াটির ডেমন পতাকা, একটি বুলিয়ান মান। শুরু () বলার আগে এটি অবশ্যই সেট করতে হবে।

প্রাথমিক মানটি তৈরির প্রক্রিয়া থেকে উত্তরাধিকার সূত্রে প্রাপ্ত।

যখন কোনও প্রক্রিয়াটি প্রস্থান করে, তখন এটির সমস্ত ডিমনিক শিশু প্রক্রিয়াগুলি বন্ধ করার চেষ্টা করে।


6
আমি বুঝতে পেরেছিলাম যে p.daemon=True"ব্যাকগ্রাউন্ড প্রক্রিয়া শুরু করার জন্য যা মূল প্রোগ্রামটি অব্যাহত না করা থেকে চালিত হয়"। তবে "যদি মূল প্রোগ্রামটি প্রস্থান হওয়ার আগে ডেমন প্রক্রিয়াটি স্বয়ংক্রিয়ভাবে শেষ হয়ে যায়" তবে এর সঠিক ব্যবহারটি কী?
মাইকিএলএল

8
@ মাইকিএলএল মূলত আপনি যতক্ষণ পিতামাতার প্রক্রিয়া চলছে ততক্ষণ পটভূমিতে যা চান তা কিন্তু মূল প্রোগ্রামটি থেকে বেরিয়ে আসার আগে এটিকে নিখুঁতভাবে পরিষ্কার করার দরকার নেই। সম্ভবত এমন কোনও কর্মী প্রক্রিয়া যা সকেট বা হার্ডওয়্যার ডিভাইস থেকে ডেটা পড়ে এবং সেই ডেটাটিকে কোনও কাতারের মাধ্যমে পিতামাতার কাছে ফিরিয়ে দেয় বা কোনও উদ্দেশ্যে ব্যাকগ্রাউন্ডে প্রক্রিয়া করে? সাধারণভাবে আমি বলব যে daemonicশিশু প্রক্রিয়া ব্যবহার করা খুব নিরাপদ নয়, কারণ এতে থাকা কোনও উন্মুক্ত সংস্থান পরিষ্কার করার অনুমতি না দিয়ে প্রক্রিয়াটি সমাপ্ত হতে চলেছে .. (চালনা)।
ড্যানো

7
@ মাইকিএলএল একটি ভাল অনুশীলন হ'ল মূল প্রক্রিয়াটি বের হওয়ার আগে বাচ্চাকে পরিষ্কার করা এবং প্রস্থান করার সিগন্যাল দেওয়া। আপনি মনে করতে পারেন পিতামাতার প্রস্থানকালে ডেমোনিক শিশু প্রক্রিয়াটি চালিয়ে যাওয়া বুদ্ধিমান হয়ে উঠবে, তবে মনে রাখবেন যে এপিআই যত তাড়াতাড়ি সম্ভব এপিআইয়ের multiprocessingঅনুকরণ করার জন্য ডিজাইন করা হয়েছে threading। দৈত্যাদিসংক্রান্ত threading.Threadবস্তু যত তাড়াতাড়ি মূল থ্রেড প্রস্থানের যেমন, তাই দৈত্যাদিসংক্রান্ত সমাপ্ত multiprocesing.Processএকই এইরকম আচরণ বস্তু।
ড্যানো

38

ছাড়া join(), শিশু প্রক্রিয়া করার আগেই মূল প্রক্রিয়াটি শেষ হতে পারে। আমি নিশ্চিত না যে কোন পরিস্থিতিতে জম্বিবাদে বাড়ে।

এর মূল উদ্দেশ্যটি join()শিশু প্রক্রিয়াটির কাজের উপর নির্ভর করে মূল প্রক্রিয়াটি যে কোনও কিছু করার আগে কোনও শিশু প্রক্রিয়া শেষ হয়েছে তা নিশ্চিত করা।

এর ব্যুৎপত্তিটি এর join()বিপরীত fork, যা শিশু প্রক্রিয়া তৈরির জন্য ইউনিক্স-পরিবার অপারেটিং সিস্টেমে সাধারণ শব্দ। একটি একক প্রক্রিয়া বেশ কয়েকটিতে "কাঁটাচামচ" করে, তারপরে একটিতে "যোগ দেয়"।


2
এটি নামটি ব্যবহার করে join()কারণ join()কোনও threading.Threadজিনিসটি সম্পূর্ণ হওয়ার জন্য অপেক্ষা করার জন্য যা ব্যবহার করা হয় , এবং multiprocessingAPI হ'ল threadingসম্ভব যতটা সম্ভব নকল করা ।
ড্যানো

আপনার দ্বিতীয় বিবৃতিটি একটি বর্তমান প্রকল্পে আমি যে সমস্যার সাথে মোকাবিলা করছি তার সমাধান করে।
মাইকেইলএল

আমি সেই অংশটি বুঝতে পেরেছি যেখানে মূল থ্রেডটি সাব-প্রক্রিয়াটি শেষ হওয়ার জন্য অপেক্ষা করে, তবে কি এই ধরণের পরাজয় অ্যাসিঙ্ক্রোনাস মৃত্যুদন্ডের উদ্দেশ্য নয়? স্বাধীনভাবে (উপ-কাজ বা প্রক্রিয়া) ফাঁসির কাজ শেষ করার কথা নয়?
অপূর্ব কুনকুলল

1
@ অপূর্বকানকুলল আপনি কীভাবে এটি ব্যবহার করছেন তার উপর নির্ভর করে join()তবে মূল থ্রেডে সাব-থ্রেডের কাজের ফলাফলের প্রয়োজন রয়েছে এমন ক্ষেত্রে প্রয়োজন। উদাহরণস্বরূপ, আপনি যদি কিছু উপস্থাপন করছেন এবং 4 টি উপ-প্রসেসের প্রতিটিতে চূড়ান্ত চিত্রের 1/4 বরাদ্দ করেন, এবং কাজটি শেষ হয়ে গেলে পুরো চিত্রটি প্রদর্শন করতে চান।
রাসেল বোরোগোভ

@ রাসেলবোরোগোভ আহ! আমি এটা পাই. তারপরে অ্যাসিক্রোনাস ক্রিয়াকলাপটির অর্থ এখানে কিছুটা আলাদা। এটির অর্থ কেবলমাত্র এটিকে বোঝাতে হবে যে উপ-প্রক্রিয়াগুলি মূল থ্রেডের সাথে একই সাথে তাদের কাজগুলি পরিচালনা করতে বোঝায় যখন মূল থ্রেডটি কেবল উপ-প্রক্রিয়াগুলিতে অপেক্ষা করার পরিবর্তে এটির কাজ করে।
অপূর্ব কুনকুলোল

12

আমি কী joinকরে সে সম্পর্কে বিস্তারিত জানাতে যাচ্ছি না , তবে এখানে ব্যুৎপত্তি এবং এর পিছনে অন্তর্নিহিততা রয়েছে যা আপনাকে এর অর্থ আরও সহজে স্মরণে রাখতে সহায়তা করবে।

ধারণাটি হ'ল মৃত্যুদণ্ড কার্যকর করা একাধিক প্রক্রিয়াতে " কাঁটাচামচ " হয় যার মধ্যে একজন হলেন মাস্টার, বাকী শ্রমিক (বা "ক্রীতদাস")। কর্মীরা হয়ে গেলে, তারা মাস্টারকে "যোগ দেয়" যাতে সিরিয়াল কার্যকর করা আবার শুরু করা যায়।

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

"কাঁটাচামচ" এবং "যোগদান" নামগুলি 1963 সাল থেকে বহু অর্থ প্রক্রিয়ায় এই অর্থ সহ ব্যবহৃত হয় ।


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

1
একাধিক প্রক্রিয়াতে ব্যবহার থেকে উদ্বেগজনকভাবে ব্যবহারের সম্ভাবনা কম; বরং উভয় ইন্দ্রিয়ই শব্দের স্পষ্ট-ইংরাজী অনুভূতি থেকে পৃথক পৃথক হয়ে উঠেছে।
রাসেল বোরোগোভ

2

join()কর্মী প্রসেসগুলি প্রস্থান করার জন্য অপেক্ষা করতে ব্যবহৃত হয়। এক কল করতে হবে close()বা terminate()ব্যবহার করার পূর্বে join()

ভালো লেগেছে @Russell উল্লিখিত যোগদানের বিপরীত মত হল কাঁটাচামচ (যা spawns উপ-প্রসেস)।

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

"the child process will sit idle and not terminate, becoming a zombie you must manually kill" এটি সম্ভব যখন মূল (পিতামাতার) প্রক্রিয়াটি প্রস্থান করে তবে শিশু প্রক্রিয়াটি এখনও চলছে এবং একবার সম্পূর্ণ হয়ে গেলে এর প্রস্থান স্থিতিতে ফিরে আসার কোনও পিতামাতার প্রক্রিয়া নেই।


2

দ্য join()কল নিশ্চিত করে যে আপনার কোড পরবর্তী লাইন সব মাল্টিপ্রসেসিং প্রসেস সম্পন্ন হওয়ার আগে বলা নেই।

উদাহরণস্বরূপ, নীচে join(), নিম্নলিখিত restart_program()কোডগুলি প্রক্রিয়া শেষ হওয়ার আগেই কল করবে , যা অ্যাসিঙ্ক্রোনাসের অনুরূপ এবং আমরা যা চাই তা নয় (আপনি চেষ্টা করতে পারেন):

num_processes = 5

for i in range(num_processes):
    p = multiprocessing.Process(target=calculate_stuff, args=(i,))
    p.start()
    processes.append(p)
for p in processes:
    p.join() # call to ensure subsequent line (e.g. restart_program) 
             # is not called until all processes finish

restart_program()

0

কোনও প্রক্রিয়াটি এর কাজ শেষ না হয়ে শেষ না হওয়া পর্যন্ত অপেক্ষা করতে, যোগ () পদ্ধতিটি ব্যবহার করুন।

এবং

দ্রষ্টব্য সমাপ্তি প্রতিফলিত করার জন্য পটভূমি যন্ত্রপাতিটির অবজেক্টের স্থিতি আপডেট করার সময় দেওয়ার জন্য প্রক্রিয়াটি সমাপ্ত হওয়ার পরে () প্রক্রিয়ায় যোগদান করা গুরুত্বপূর্ণ।

এটি একটি ভাল উদাহরণ আমাকে এটি বুঝতে সাহায্য করেছে: এখানে

একটি জিনিস আমি ব্যক্তিগতভাবে লক্ষ্য করেছি তা হল আমার মূল প্রক্রিয়াটি বিরত হওয়া পর্যন্ত শিশুটি যোগদান () পদ্ধতিটি ব্যবহার করে আমার প্রক্রিয়াটি শেষ না করে দিয়েছিল যা আমার অবস্থানটিকে multiprocessing.Process()প্রথম স্থানে ব্যবহার করে পরাজিত করে ।

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