क्या फोर्क कहते समय धागे की नकल की जाती है?


31

अगर मेरे पास थ्रेड्स के साथ चलने और fork()यूनिक्स-आधारित सिस्टम पर कॉल करने का प्रोग्राम है, तो क्या थ्रेड्स कॉपी किए गए हैं? मुझे पता है कि वर्तमान प्रक्रिया के लिए वर्चुअल मेमोरी को 1: 1 में कॉपी की गई नई प्रक्रिया में कॉपी किया गया है। मुझे पता है कि एक प्रक्रिया की आभासी मेमोरी में थ्रेड्स का अपना स्टैक होता है। इस प्रकार, कम से कम धागे के ढेर को भी कॉपी किया जाना चाहिए। हालाँकि, मुझे नहीं पता कि थ्रेड्स के लिए कुछ और है जो वर्चुअल मेमोरी में नहीं रहता है और इस प्रकार इसे कॉपी नहीं किया जाता है। यदि ऐसा नहीं है, तो क्या दो प्रक्रियाएं थ्रेड साझा करती हैं या क्या वे स्वतंत्र प्रतियां हैं?

जवाबों:


29

नहीं।

धागे की नकल नहीं की जाती है fork()। POSIX विनिर्देश कहता है (जोर मेरा है):

कांटा - एक नई प्रक्रिया बनाएँ

एकल थ्रेड के साथ एक प्रक्रिया बनाई जाएगी । यदि एक बहु-थ्रेडेड प्रक्रिया फोर्क () को बुलाती है, तो नई प्रक्रिया में कॉलिंग थ्रेड की प्रतिकृति और इसका पूरा पता स्थान होगा, जिसमें संभवतः म्यूटेक्स और अन्य संसाधन शामिल हैं। नतीजतन, त्रुटियों से बचने के लिए, बच्चे की प्रक्रिया केवल तब तक async-signal-safe संचालन निष्पादित कर सकती है जब तक कि निष्पादन कार्यों में से एक को कॉल नहीं किया जाता है।

इस समस्या को दरकिनार करने के लिए, pthread_atfork()मदद करने के लिए एक फ़ंक्शन मौजूद है ।


7

आदमी कांटा :

बच्चे की प्रक्रिया एक एकल धागे के साथ बनाई गई है - जिसे कांटा () कहा जाता है। माता-पिता के पूरे आभासी पते की जगह बच्चे में दोहराई जाती है, जिसमें म्यूटेक्स, स्थिति चर और अन्य pthreads ऑब्जेक्ट शामिल हैं; pthread_atfork (3) का उपयोग उन समस्याओं से निपटने में मददगार हो सकता है जो इसका कारण बन सकती हैं।


लेकिन यह अजीब लगता है: यदि वास्तविक थ्रेड्स (जो मुझे नहीं पता है कि वर्चुअल मेमोरी के अलावा कहीं और स्टोरेज नहीं है) में फोर्क की कॉलिंग प्रक्रिया के लिए स्टैक को कॉपी क्यों किया जाएगा?

खैर यह क्यों एक अलग सवाल है। मुझे मूल डिज़ाइन निर्णयों की जानकारी नहीं है जो उस कार्यान्वयन के लिए प्रेरित करते हैं। यदि आप रुचि रखते हैं तो आपको एक अलग प्रश्न के रूप में पूछना चाहिए।
kaylum

@dip लेकिन अन्य धागों के ढेर की नकल नहीं की गई है, ऐसा किसने कहा?
जीन-बैप्टिस्ट युनुस

1
@ जीन-बैप्टिस्टयूनस यूनिक्स सिस्टम में, एक प्रक्रिया के लिए वर्चुअल मेमोरी का प्रतिनिधित्व करने वाली एक संरचना है। वह एक नकल है। सिर्फ ढेर और बीएसएस नहीं

6
आपको संपूर्ण मेमोरी स्पेस मिलता है - और इसलिए सभी थ्रेड्स के ढेर। आपको इसकी आवश्यकता है क्योंकि जहां कोई सूत्र नहीं है जहां शेष धागे तक पहुंचने वाले स्टैक (या स्थिर मेमोरी) में रहने वाले पॉइंटर्स इंगित कर रहे हैं - वे बहुत अच्छी तरह से डेटा की ओर इशारा कर सकते हैं जो मूल प्रक्रिया में कुछ थ्रेड के स्टैक में रहते थे
davidarak

4

ओपन ग्रुप बेस स्पेसिफिकेशन्स अंक 7, 2018 संस्करण के कांटे से :

एकल थ्रेड के साथ एक प्रक्रिया बनाई जाएगी। यदि एक बहु-थ्रेडेड प्रक्रिया फोर्क () को बुलाती है , तो नई प्रक्रिया में कॉलिंग थ्रेड की प्रतिकृति और इसका पूरा पता स्थान होगा, जिसमें संभवतः म्यूटेक्स और अन्य संसाधन शामिल हैं। नतीजतन, त्रुटियों से बचने के लिए, बच्चे की प्रक्रिया केवल तब तक async-signal-safe संचालन निष्पादित कर सकती है जब तक कि निष्पादन कार्यों में से एक को कॉल नहीं किया जाता है।

जब एप्लिकेशन सिग्नल हैंडलर से कांटा () और pthread_atfork () द्वारा पंजीकृत किसी भी कांटा हैंडलर को एक फ़ंक्शन को कॉल करता है जो async-signal-safe नहीं है, तो व्यवहार अपरिभाषित है।


-2

मूल रूप से, "कांटा" को एक अलग थ्रेड में पढ़ने के बजाय डिस्क को लिखने और फिर काम करने के लिए प्राप्त किया गया था (जो कि किसी अन्य के साथ कार्य को स्वैप करने पर किया जाएगा), छवि में कार्य आईडी को संशोधित करना और फिर भी जारी रखना इसके निष्पादन (नए कार्य के रूप में) के साथ। यह बुनियादी कार्य स्विचिंग तंत्र के लिए एक बहुत ही सरल संशोधन था, जहां एक समय में केवल एक ही कार्य रैम मेमोरी पर कब्जा कर लेता था।

निश्चित रूप से, स्मृति प्रबंधन को अधिक विस्तृत होने के कारण इस योजना को नए परिवेश के अनुरूप संशोधित किया गया।


जिज्ञासु ऐसा क्यों था कि उसे वोट दिया गया था। यह यूनिक्स ने जिस तरह से किया है।
हॉट लक्स

यह दिलचस्प अंतर्दृष्टि है, लेकिन यह थ्रेड्स का उल्लेख कहां करता है? मेरे लिए एक जवाब की तरह नहीं दिखता है।
बंजर भूमि
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.