लिनुस टोरवाल्ड्स (torvalds@cs.helsinki.fi)
Tue, 6 Aug 1996 12:47:31 +0300 (EET DST)
द्वारा क्रमबद्ध संदेश: [तिथि] [धागा] [विषय] [लेखक]
अगला संदेश: बर्न पी। ज़िलर: "Re: Oops in get_hash_table"
पिछला संदेश: लिनुस टोरवाल्ड्स: "रे: आई / ओ अनुरोध आदेश"
सोम पर, 5 अगस्त 1996, पीटर पी। ईसरलोह ने लिखा:
हमें धागे की अवधारणा को स्पष्ट रखने की आवश्यकता है। बहुत से लोग एक प्रक्रिया के साथ एक थ्रेड को भ्रमित करने लगते हैं। निम्नलिखित चर्चा लिनेक्स की वर्तमान स्थिति को नहीं दर्शाती है, बल्कि उच्च स्तरीय चर्चा में बने रहने का प्रयास है।
नहीं!
यह सोचने का कोई कारण नहीं है कि "थ्रेड" और "प्रक्रिया" अलग-अलग संस्थाएं हैं। पारंपरिक रूप से ऐसा ही किया जाता है, लेकिन मुझे लगता है कि इस तरह से सोचना एक बड़ी गलती है। इस तरह से सोचने का एकमात्र कारण ऐतिहासिक सामान है।
दोनों धागे और प्रक्रियाएं वास्तव में सिर्फ एक चीज हैं: एक "निष्पादन का संदर्भ"। अलग-अलग मामलों को कृत्रिम रूप से अलग करने की कोशिश सिर्फ आत्म-सीमित है।
एक "निष्पादन का संदर्भ", जिसे COE कहा जाता है, उस COE के सभी राज्य का समूह है। उस राज्य में सीपीयू राज्य (रजिस्टर आदि), एमएमयू राज्य (पेज मैपिंग), अनुमति राज्य (यूआईडी, जीआईडी) और विभिन्न "संचार राज्य" (खुली फाइलें, सिग्नल हैंडलर आदि) जैसी चीजें शामिल हैं। परंपरागत रूप से, एक "थ्रेड" और एक "प्रक्रिया" के बीच का अंतर मुख्य रूप से यह रहा है कि एक थ्रेड में CPU स्थिति (+ संभवतः कुछ अन्य न्यूनतम स्थिति) होती है, जबकि अन्य सभी संदर्भ प्रक्रिया से आते हैं। हालाँकि, यह सिर्फ
एक है COE की कुल स्थिति को विभाजित करने तरीका है, और ऐसा कुछ भी नहीं है जो कहता है कि यह इसे करने का सही तरीका है। उस तरह की छवि के लिए खुद को सीमित करना सिर्फ सादा बेवकूफी है।
जिस तरह से लिनक्स इस बारे में सोचता है (और जिस तरह से मैं काम करने के लिए चीजें चाहते हैं) वहाँ वह यह है कि है एक "प्रक्रिया" या एक "सूत्र" जैसी कोई चीज नहीं। केवल COE (लिनक्स द्वारा "कार्य" कहा जाता है) की समग्रता है। विभिन्न सीओई अपने संदर्भ के हिस्सों को एक दूसरे के साथ साझा कर सकते हैं, और एक सबसेट उस साझाकरण का पारंपरिक "थ्रेड" / "प्रक्रिया" सेटअप है, लेकिन इसे वास्तव में केवल एक उप-वर्ग के रूप में देखा जाना चाहिए (यह एक महत्वपूर्ण सबसेट है, लेकिन वह महत्व आता है डिजाइन से नहीं, बल्कि मानकों से: हम निष्पक्ष रूप से लिनक्स के शीर्ष पर मानकों के अनुरूप धागे कार्यक्रम चलाना चाहते हैं)।
संक्षेप में: सोच के थ्रेड / प्रोसेस तरीके के आसपास डिज़ाइन न करें। कर्नेल को सोचने के COE तरीके के आसपास डिज़ाइन किया जाना चाहिए, और फिर pthreads लाइब्रेरी उन उपयोगकर्ताओं को सीमित pthreads इंटरफ़ेस निर्यात कर सकती है जो COE को देखने के उस तरीके का उपयोग करना चाहते हैं।
जब आप थ्रेड / प्रक्रिया के विपरीत COE सोचते हैं तो क्या संभव हो जाता है, उदाहरण के रूप में:
- आप एक बाहरी "सीडी" प्रोग्राम कर सकते हैं, कुछ ऐसा जो पारंपरिक रूप से UNIX और / या प्रक्रिया / थ्रेड (मूर्खतापूर्ण उदाहरण) में असंभव है, लेकिन विचार यह है कि आपके पास इन प्रकार के "मॉड्यूल" हो सकते हैं जो पारंपरिक UNIX तक सीमित नहीं हैं / थ्रेड्स सेटअप)। एक करो:
क्लोन (CLONE_VM | CLONE_FS);
बच्चा: निष्पादित ("बाहरी-सीडी");
/ * "निष्पादित करें ()" VM को अलग कर देगा, इसलिए हमने CLONE_VM का उपयोग करने का एकमात्र कारण क्लोनिंग के कार्य को तेज करना था * /
- आप स्वाभाविक रूप से "vfork ()" कर सकते हैं (यह न्यूनतम कर्नेल समर्थन को मात देता है, लेकिन यह समर्थन पूरी तरह से सोचने के CUA तरीके को फिट करता है):
क्लोन (CLONE_VM);
बच्चा: दौड़ना जारी रखें, अंततः निष्पादित करें ()
माँ: निष्पादित करने के लिए प्रतीक्षा करें
- आप बाहरी "आईओ डेमॉन" कर सकते हैं:
क्लोन (CLONE_FILES);
बच्चा: ओपन फाइल डिस्क्रिप्टर आदि
माँ: fd के बच्चे को खोला और vv का उपयोग करें।
उपरोक्त सभी कार्य क्योंकि आप सोच के थ्रेड / प्रोसेस तरीके से बंधे नहीं हैं। उदाहरण के लिए एक वेब सर्वर के बारे में सोचें, जहां CGI लिपियों को "निष्पादन के धागे" के रूप में किया जाता है। आप पारंपरिक थ्रेड्स के साथ ऐसा नहीं कर सकते, क्योंकि पारंपरिक थ्रेड्स को हमेशा पूरे एड्रेस स्पेस को साझा करना होता है, इसलिए आपको उन सभी चीजों से लिंक करना होगा जो आप वेब सर्वर में स्वयं करना चाहते थे ("थ्रेड" नहीं चल सकता है) एक और निष्पादन योग्य)।
समस्या एक "निष्पादन के संदर्भ" के रूप में इस के बारे में सोच के बजाय, अपने कार्यों को अब बाहरी प्रोग्राम पर अमल (= माता पिता से पता स्थान अलग करता है) आदि के लिए चुना जा सकता है अगर वे चाहते हैं, या वे माता पिता के साथ उदाहरण के शेयर सब कुछ के लिए कर सकते हैं को छोड़कर के लिए फ़ाइल विवरणक (ताकि उप- "थ्रेड्स" बहुत सारी फाइलें खोल सकें, जिनके बारे में माता-पिता को चिंता करने की आवश्यकता न हो: वे स्वचालित रूप से बंद हो जाते हैं जब उप- "थ्रेड" बाहर निकलता है, और यह माता-पिता में fd का उपयोग नहीं करता है) ।
उदाहरण के लिए, एक थके हुए "inetd" के बारे में सोचें। आप कम ओवरहेड कांटा + निष्पादित करना चाहते हैं, इसलिए लिनक्स तरीके से आप "कांटा ()" का उपयोग करने के बजाय एक बहु-थ्रेडेड इनसेट लिख सकते हैं, जहां प्रत्येक थ्रेड सिर्फ CLONE_VM (शेयर एड्रेस स्पेस) के साथ बनाया जाता है, लेकिन फ़ाइल न भेजें विवरणक आदि)। तब बच्चा निष्पादित कर सकता है यदि यह एक बाहरी सेवा थी (उदाहरण के लिए rlogind), या शायद यह आंतरिक inetd सेवाओं में से एक था (गूंज, टाइमफॉइड) जिस स्थिति में यह सिर्फ बात करता है और बाहर निकलता है।
आप "थ्रेड" / "प्रक्रिया" के साथ ऐसा नहीं कर सकते।
लीनुस