बहुत सारे "निचले" विवरण हैं।
पहले, विचार करें कि कर्नेल में प्रक्रियाओं की एक सूची है, और किसी भी समय, इनमें से कुछ प्रक्रियाएं चल रही हैं, और कुछ नहीं हैं। कर्नेल प्रत्येक चलने की प्रक्रिया को सीपीयू समय के कुछ स्लाइस की अनुमति देता है, फिर इसे बाधित करता है और अगले पर जाता है। यदि कोई रन करने योग्य प्रक्रियाएं नहीं हैं, तो कर्नेल संभवतः CPU को HLT जैसा निर्देश जारी करेगा जो CPU को तब तक निलंबित करता है जब तक कि कोई हार्डवेयर व्यवधान न हो।
सर्वर में कहीं एक सिस्टम कॉल है जो कहता है "मुझे कुछ करने के लिए दो"। इसे करने के दो तरीके हैं। अपाचे के मामले में, यह accept
एक सॉकेट पर कॉल करता है। अपाचे पहले खोला गया है, शायद पोर्ट 80 पर सुन रहा है। कर्नेल कनेक्शन प्रयासों की एक कतार बनाए रखता है, और टीसीपी SYN प्राप्त होने पर हर बार उस कतार में जुड़ जाता है । एक कर्नेल को पता है कि टीसीपी SYN प्राप्त किया गया था, डिवाइस ड्राइवर पर निर्भर करता है; कई एनआईसी के लिए नेटवर्क डेटा प्राप्त होने पर संभवतः एक हार्डवेयर अवरोध होता है।
accept
कर्नेल से मुझे अगला कनेक्शन दीक्षा देने के लिए कहता है। यदि कतार खाली नहीं थी, तो accept
बस तुरंत वापस आ जाती है। यदि कतार खाली है, तो प्रक्रिया (अपाचे) को चलने वाली प्रक्रियाओं की सूची से हटा दिया जाता है। जब एक कनेक्शन बाद में शुरू किया जाता है, तो प्रक्रिया फिर से शुरू हो जाती है। इसे "अवरुद्ध करना" कहा जाता है, क्योंकि इसे कॉल करने की प्रक्रिया के कारण, accept()
एक फ़ंक्शन की तरह दिखता है जो तब तक वापस नहीं आता है जब तक कि इसका कोई परिणाम न हो, जो अब से कुछ समय हो सकता है। उस समय के दौरान प्रक्रिया कुछ और नहीं कर सकती है।
एक बार accept
लौटते समय, अपाचे जानता है कि कोई व्यक्ति कनेक्शन शुरू करने का प्रयास कर रहा है। यह फिर दो समान प्रक्रियाओं में अपाचे प्रक्रिया को विभाजित करने के लिए कांटा कहता है। इनमें से एक प्रक्रिया HTTP अनुरोध को संसाधित करने के लिए जाती है, दूसरे accept
को अगला कनेक्शन प्राप्त करने के लिए फिर से कॉल करता है। इस प्रकार, हमेशा एक मास्टर प्रक्रिया होती है जो accept
उप-प्रक्रियाओं को कॉल और स्पॉन करने के अलावा कुछ नहीं करती है, और फिर प्रत्येक अनुरोध के लिए एक उप-प्रक्रिया होती है।
यह एक सरलीकरण है: प्रक्रियाओं के बजाय थ्रेड्स के साथ ऐसा करना संभव है, और यह fork
पहले से संभव भी है इसलिए अनुरोध प्राप्त होने पर एक कार्यकर्ता प्रक्रिया तैयार है, इस प्रकार स्टार्टअप ओवरहेड को कम करना। यह अपाचे को कैसे कॉन्फ़िगर किया गया है, इसके आधार पर यह इन चीजों में से एक हो सकता है।
यही कारण है कि यह कैसे करना है के पहले व्यापक श्रेणी है, और यह कहा जाता है आईओ अवरुद्ध क्योंकि सिस्टम की तरह कहता है accept
और read
और write
जो सॉकेट पर काम प्रक्रिया को निलंबित कर देगा, जब तक वे वापस जाने के लिए कुछ है।
इसे करने का दूसरा व्यापक तरीका गैर-अवरोधक या घटना आधारित या अतुल्यकालिक आईओ कहा जाता है । यह सिस्टम कॉल जैसे select
या के साथ कार्यान्वित किया जाता है epoll
। ये प्रत्येक एक ही काम करते हैं: आप उन्हें सॉकेट्स की सूची देते हैं (या सामान्य तौर पर, फाइल डिस्क्रिप्टर) और आप उनके साथ क्या करना चाहते हैं, और कर्नेल को तब तक ब्लॉक करता है जब तक कि उन चीजों में से एक करने के लिए तैयार न हो।
इस मॉडल के साथ, आप कर्नेल को बता सकते हैं (के साथ epoll
), "मुझे बताएं कि पोर्ट 80 पर एक नया कनेक्शन है या इन 9471 अन्य कनेक्शनों में से किसी एक पर पढ़ने के लिए नया डेटा है"। epoll
जब तक उन चीजों में से एक तैयार न हो जाए, तब तक आप इसे करें। फिर आप दोहराते हैं। सिस्टम कॉल की तरह accept
और read
और write
कभी नहीं ब्लॉक, भाग में, क्योंकि जब भी आप उन्हें फोन, epoll
केवल आपके बताया कि वे तैयार हैं तो वहाँ ब्लॉक करने के लिए कोई कारण नहीं होगा, और इसलिए भी क्योंकि जब आप सॉकेट या फ़ाइल आपके द्वारा निर्दिष्ट खोलने आप उन्हें चाहते हैं कि गैर-अवरुद्ध मोड में, इसलिए वे कॉल EWOULDBLOCK
अवरुद्ध होने के बजाय विफल हो जाएंगे ।
इस मॉडल का लाभ यह है कि आपको केवल एक प्रक्रिया की आवश्यकता है। इसका मतलब है कि आपको प्रत्येक अनुरोध के लिए स्टैक और कर्नेल संरचनाओं को आवंटित करने की आवश्यकता नहीं है। Nginx और HAProxy इस मॉडल का उपयोग करते हैं, और यह एक बड़ा कारण है कि वे समान हार्डवेयर पर Apache की तुलना में इतने अधिक कनेक्शन से निपट सकते हैं।