ठोस उदाहरण
मैं कुछ वास्तविक दुनिया के उदाहरणों को जोड़ना चाहूंगा, और उन्हें सॉफ्टवेयर इंजीनियरिंग की दुनिया से जोड़ना चाहूंगा। सबसे पहले, कुछ पर विचार करें जो मुझे उम्मीद है कि "तुल्यकालिक" की आपकी सहज परिभाषा से मेल खाती है: कुछ परिस्थितियों में फायरफ्लाइज़ की चमकती चमक । दूसरा, 4x100 महिलाओं की ओलंपिक रिले रेस पर विचार करें । तीसरा, सैन्य फिल्मों से उस पुरानी ट्रॉप पर विचार करें: "पुरुष, अपनी घड़ियों को सिंक्रनाइज़ करें!"
अब, चलिए सोचते हैं कि क्या चल रहा है। आइए यह देखते हुए शुरू करें कि ये सभी चीजें प्रक्रियाएं हैं , या समय में विस्तारित हुई इकाइयां । यह कहने का कोई मतलब नहीं है कि एक कटोरा "सिंक्रोनस" है और रॉक "एसिंक्स" है। दूसरा, टैंगो में दो लगते हैं । आप यह नहीं कह सकते कि "एक धावक सिंक है"। किसके साथ सिंक करें? अंत में, दो प्रक्रियाओं के लिए एक ही समय में कुछ करने के लिए, जब तक कि उनके पास पहले से ही समान आवृत्ति और चरण न हो, एक या दोनों को इंतजार करना चाहिए ।
विश्लेषण
जब शब्दकोश परिभाषा कहती है कि सिंक में दो इकाइयाँ "एक ही समय में होती हैं या मौजूद होती हैं", जो फायरफ्लाइज़ से प्रकाश की अवधारणा के साथ बहुत अच्छी तरह संरेखित होती हैं। दुर्भाग्य से, यह कहना कि प्रकाश "सिंक में" है, यह कहने का एक सुस्त तरीका है कि जुगनू प्रकाश प्रक्रियाओं को सिंक्रनाइज़ करते हैं।
तो फायरफ्लाइज़ का एक समूह कैसे हो सकता है, जिनके पास संभवतः Apple स्मार्टवॉच और NTP उनके मार्गदर्शन करने के लिए नहीं हैं, एक ही समय में उनके पीछे के छोरों को फ्लैश करने का प्रबंधन करें? ठीक है, यह बहुत आसान है अगर उनके पास एक सुसंगत टेम्पो सेट करने का साधन है और इसके लिए छोटे समायोजन कर सकते हैं। वे बस फ्लैश करते हैं, और यदि अधिक लोग उनके ठीक बाद फ्लैश करते हैं, तो वे धीमा हो जाते हैं (देरी को बढ़ाते हैं), जबकि यदि उनके सामने अधिक फ्लैश सही होता है, तो वे गति बढ़ाते हैं (देरी को घटाते हैं)। इसलिए वे अनिवार्य रूप से एक ही टेम्पो और चरण पर पहुंचने के लिए एक सरल फीडबैक प्रक्रिया का उपयोग कर सकते हैं। यहां महत्वपूर्ण अवलोकन यह ध्यान रखना है कि वे फ्लैश करने के लिए सही क्षण की प्रतीक्षा करके समकालिकता प्राप्त करते हैं ।
4x100 की दौड़ दिलचस्प है क्योंकि आप कार्रवाई में प्रक्रिया के समय के दोनों रूपों को देखते हैं : एक टीम के भीतर धावकों को सिंक्रनाइज़ किया जाता है, जबकि अलग-अलग टीमों के धावक "async" होते हैं। रिले में दूसरा धावक तब तक इंतजार करना चाहिए जब तक कि पहला धावक स्थानांतरण क्षेत्र में प्रवेश न कर जाए । हैंड-ऑफ उन दो धावकों के बीच एक समकालिक घटना है। हालाँकि, अलग-अलग गलियों में चलने वालों को परवाह नहीं है कि एक और लेन में क्या हो रहा है , और सबसे निश्चित रूप से धीमा नहीं है और सिंक में अपने हाथ से काम करते हैं। धावकों की प्रत्येक लेन एक दूसरे के संबंध में अतुल्यकालिक है। फिर, हम देखते हैं कि तुल्यकालन प्रतीक्षा की ओर जाता है, जबकि अतुल्यकालिक नहीं होता है।
अंत में, एक कंपनी (पलटन, फायर टीम, आदि) में सैनिकों को अपनी घड़ियों को सिंक्रनाइज़ करना चाहिए ताकि वे एक ही समय में दुश्मन पर हमला कर सकें । हो सकता है कि कुछ सैनिक दूसरों के सामने अपनी स्थिति पर पहुंचें, या दुश्मन पर जल्द ही फायर करने का अवसर हो। लेकिन एक साथ होने वाला हमला आमतौर पर आश्चर्य के तत्व की वजह से एक खतरनाक हमले की तुलना में अधिक प्रभावी होता है। इसलिए समकालिकता हासिल करने के लिए, सैनिकों में से कई को कार्य करने के लिए नियत समय की प्रतीक्षा करनी चाहिए ।
निर्धारक विशेषता
यह इंतजार करने पर जोर क्यों? खैर, यह इसलिए है क्योंकि प्रतीक्षा वह परिभाषित करने वाली विशेषता है जो अतुल्यकालिक प्रक्रियाओं से सिंक्रोनस को अलग करती है। यदि आपके पास दो प्रक्रियाएं हैं जिनके बारे में आप कुछ नहीं जानते हैं, तो आपको डिफ़ॉल्ट रूप से मान लेना चाहिए कि वे अतुल्यकालिक हैं। उदाहरण के लिए, एक पैकेज वितरण और एक एम्बुलेंस द्वारा ड्राइविंग सबसे अधिक संभावना नहीं है । यह प्रदर्शित करने के लिए कि दो प्रक्रियाएं, वास्तव में, सिंक्रनाइज़ हैं, आपको समय में एक बहुत ही विशेष क्षण खोजने की आवश्यकता है: सिंक्रनाइज़ेशन बिंदु ।
एक पैकेज ड्रायवर और एक एम्बुलेंस को अस्पताल ले जाते हुए एक डिलीवरी ड्रायवर आम तौर पर किसी भी समय को साझा नहीं करता है जिसे हम "सिंक्रोनाइज़ेशन पॉइंट" के रूप में पहचानते हैं। दूसरी ओर, यूनिसन में चमकती हुई फायरफ्लाइज़ में हर बार फ्लैश होने पर एक सिंक पॉइंट होता है, रिले धावक हर बार एक बार सिंक करते हैं जब वे बैटन को सौंपते हैं, और सैनिकों के पास एक सिंक पॉइंट होता है जब वे अपना हमला करते हैं। यदि आप एक या अधिक समन्वयन बिंदुओं की पहचान कर सकते हैं, तो प्रक्रियाएं सिंक्रनाइज़ की जाती हैं । इसे समझना आसान होना चाहिए, क्योंकि "सिन-" एक ग्रीक उपसर्ग है जिसका अर्थ है "या" एक साथ ", और" क्रोनो " " समय "के लिए ग्रीक मूल है । "सिंक्रोनाइज़्ड" का शाब्दिक अर्थ है "एक ही समय में",
सीमाओं
ध्यान दें कि "सिंक्रनाइज़ेशन" आवश्यक रूप से या तो या दोनों प्रक्रियाओं के पूरे जीवनकाल पर लागू नहीं होता है। मैं यह तर्क दूंगा कि यह केवल "वेटिंग टाइम तक और सिंक्रोनाइज़ेशन पॉइंट (एस) सहित" पर लागू होता है। इस प्रकार, दो प्रक्रियाएँ अतुल्यकालिक रूप से संचालित हो सकती हैं जब तक कि वे एक ऐसी स्थिति तक नहीं पहुँचते जहाँ उन्हें संवाद करने की आवश्यकता होती है, तब वे सिंक्रनाइज़ हो जाती हैं, सूचना का आदान-प्रदान करती हैं, और बाद में अतुल्यकालिक रूप से जारी रहती हैं। एक साधारण उदाहरण कॉफी के लिए किसी से मिल रहा है। जाहिर है, बैठक एक सिंक्रनाइज़ेशन बिंदु (या कई, बल्कि) है, और तथ्य यह है कि दो लोग उस बिंदु पर आते हैं, सिंक्रनाइज़ेशन प्रदर्शित करता है। हालांकि, हम यह नहीं कहेंगे कि क्योंकि दो लोग कॉफी के लिए मिले थे, वे दो मानव जीवनकाल थे"सिंक्रनाइज़" हैं। हो सकता है कि यह उनके जीवन का एकमात्र ऐसा पल था जो उन्हें मिला था, और जो कुछ वे करते हैं वह अन्यथा स्वतंत्र है।
यह भी ऐसा नहीं है कि आकस्मिक मिलने से समकालिकता प्रदर्शित होती है। यदि दो अजनबी सड़क पर एक-दूसरे को पास करते हैं, तो यह तथ्य कि वे किसी समय किसी विशेष स्थान पर हैं, समकालिकता साबित नहीं होती है। न ही यह तथ्य है कि एक व्यक्ति बस के इंतजार में एक बेंच पर बैठा है, और दूसरा व्यक्ति चलने के लिए होता है। जब वे किसी उद्देश्य के लिए मिलते हैं तो प्रक्रियाएँ केवल समकालिक होती हैं ।
सॉफ्टवेयर कनेक्शन
अब, चलो सॉफ्टवेयर में एक बहुत ही मौलिक कार्य के बारे में सोचते हैं: एक फ़ाइल से पढ़ना। जैसा कि आप शायद जानते हैं, कैश या मेन मेमोरी की तुलना में मास स्टोरेज आमतौर पर हजारों से लाखों गुना धीमा होता है। इस कारण से, ऑपरेटिंग सिस्टम और प्रोग्रामिंग लैंग्वेज लाइब्रेरी आमतौर पर सिंक्रोनस और एसिंक्रोनस I / O ऑपरेशंस दोनों प्रदान करते हैं। अब, भले ही आपके कार्यक्रम में केवल एक ही धागा हो, आपको ओएस के बारे में इस चर्चा के प्रयोजनों के लिए एक "अलग प्रक्रिया" के रूप में सोचना चाहिए।
सिंक
जब आप "सिंक्रोनस I / O रीड" करते हैं, तो आपके थ्रेड को डेटा उपलब्ध होने तक इंतजार करना चाहिए , जिस बिंदु पर यह जारी है। यह बहुत हद तक एक रिले रनर की तरह है जो अगले रनर को बैटन को सौंपता है, लेकिन एक रिले के बजाय केवल दो रनर्स के साथ ही ट्रैक के चारों ओर जाने की कल्पना करता है, और दूसरा रनर भी पहले से पीछे हट जाता है।
इस स्थिति में, आपके प्रोग्राम थ्रेड और OS I / O प्रक्रिया "एक ही समय में" (अभिनय) नहीं हो रही है, और इसलिए यह कहना अजीब लगता है कि ये प्रक्रिया "सिंक्रनाइज़" हैं। लेकिन यह देखने का गलत तरीका है! यह कहने जैसा है: "रिले टीम के धावक एक ही समय में नहीं चल रहे हैं, इसलिए वे सिंक्रनाइज़ नहीं हैं।" वास्तव में, दोनों कथन गलत हैं! एक रिले टीम पर धावकों करना और चाहिए लाठी के हाथ बंद: एक ही समय में चलाने के लिए, लेकिन केवल एक बहुत ही विशेष क्षण में। वास्तव में, यह दौड़ के दौरान केवल यह विशेष क्षण है जो हमें आश्वस्त करता है कि रिले टीमों के साथ शुरू करने के लिए सिंक्रनाइज़ किया जाता है! यदि हम I / O अनुरोध और प्रतिक्रिया को "बैटन" के रूप में देखते हैं,
दूसरी ओर, अगर हम सुपर कंप्यूटर पर परिमित तत्व विश्लेषण जैसी किसी चीज के बारे में सोचते हैं, तो हम देखते हैं कि बड़े पैमाने पर वैश्विक स्थिति को अपडेट करने के लिए हजारों प्रक्रियाओं को लॉक-स्टेप में काम करना चाहिए। यहां तक कि अगर कुछ नोड्स दूसरों के सामने दिए गए समय-कदम के लिए अपना काम पूरा करते हैं, तो उन्हें सभी को पूरा करने के लिए समय के कदम का इंतजार करने की आवश्यकता होती है क्योंकि परिणाम अंतरिक्ष के माध्यम से पड़ोसियों को प्रसारित करते हैं। इस तरह का सिंक्रोनाइज़ेशन फायरफ्लाइज़ की तरह है: सभी कलाकार एक ही तरह के कार्य कर रहे हैं।
प्रक्रिया विविधता
इस कारण से, हम यह देखने के लिए कुछ शर्तों का आविष्कार कर सकते हैं कि यह देखने के लिए कि तीन प्रकार की चीजें चल रही हैं: "सजातीय समकालिक", "विषम समकालिक", और "क्रमिक समकालिक"। इसलिए जब अभिनेता एक साथ एक ही कार्य कर रहे हैं (FEA, फायरफ्लाइज़), तो वे "सजातीय" हैं। जब वे एक साथ अलग-अलग कार्य कर रहे होते हैं (दौड़ने वाले बनाम रेंगते हुए बनाम अपने गंतव्यों के लिए तैरते हुए, भौतिकी बनाम ध्वनि बनाम एआई थ्रेड्स एक खेल में), वे "विषम" होते हैं। जब वे एक समय में एक कार्य कर रहे होते हैं, तो वे "अनुक्रमिक" (रिले धावक, I / O को अवरुद्ध करते हैं) होते हैं। वे बहुत अलग दिख सकते हैं, लेकिन वे एक आवश्यक संपत्ति साझा करते हैं: सभी प्रकार के अभिनेता यह सुनिश्चित करने के लिए कुछ प्रतीक्षा करते हैं कि हर कोई एक ही समय में सिंक्रनाइज़ेशन बिंदु पर पहुंचे। तुल्यकालन बिंदुओं के बीच, या "एक ही क्रिया करना" तुल्यकालन की संपत्ति के लिए अप्रासंगिक है।
एक GPU में रेंडर पाइपलाइनों को समकालिक किया जाता है क्योंकि वे सभी को एक साथ फ्रेम खत्म करना चाहिए, और एक साथ एक नया फ्रेम शुरू करना चाहिए। वे सजातीय हैं क्योंकि वे एक ही तरह का काम कर रहे हैं, और वे सभी एक साथ सक्रिय हैं। लेकिन एक सर्वर का मुख्य गेम लूप और ब्लॉकिंग इनपुट I / O थ्रेड्स, जो रिमोट इनपुट को प्रोसेस करते हैं, विषम हैं क्योंकि वे बहुत अलग तरह के काम करते हैं, और कुछ I / O थ्रेड्स कुछ भी नहीं कर पाएंगे, क्योंकि सभी नहीं कनेक्शन का उपयोग किया जाता है। फिर भी, वे सिंक्रनाइज़ हैं, क्योंकि उन्हें राज्य को परमाणु रूप से साझा करना चाहिए (एक खिलाड़ी को आंशिक गेम वर्ल्ड अपडेट नहीं देखना चाहिए, और न ही सर्वर को केवल खिलाड़ी इनपुट का एक टुकड़ा देखना चाहिए)।
async
अब, चलो एक "async I / O पढ़ा" पर विचार करें। जब आपका प्रोग्राम स्टोरेज से थोड़ा डेटा पढ़ने के लिए ओएस को रिक्वेस्ट भेजता है, तो कॉल तुरंत वापस आ जाती है । आइए कॉलबैक पर ध्यान न दें और मतदान पर ध्यान दें। सामान्य तौर पर, वह क्षण जो आपके कार्यक्रम के लिए उपलब्ध होता है, वह उस समय तक किसी विशेष बिंदु के अनुरूप नहीं होता है, जहां तक आपके प्रोग्राम के थ्रेड का संबंध है। यदि आपका प्रोग्राम स्पष्ट रूप से डेटा की प्रतीक्षा नहीं कर रहा है, तो उस पल के होने पर थ्रेड वास्तव में पता भी नहीं चलेगा। यह केवल तभी पता चलेगा कि डेटा अगली बार जाँच कर रहा है।
कोई विशेष बैठक का समय नहीं है जहां ओएस और प्रोग्राम थ्रेड डेटा को सौंपने के लिए सहमत होते हैं। वे रात में गुजरने वाले दो जहाजों की तरह हैं। अतुल्यकालिक को प्रतीक्षा की इस अनुपस्थिति की विशेषता है। बेशक, प्रोग्राम थ्रेड अक्सर I / O ऑपरेशन के बाद सभी पर इंतजार करना समाप्त कर देगा, लेकिन इसकी आवश्यकता नहीं है। यह खुशी से अन्य गणनाएं करते हुए जा सकता है जबकि I / O भ्रूण हो रहा है, और केवल बाद में जांच करें जब उसके पास एक पल हो। बेशक, एक बार जब ओएस डेटा प्राप्त कर लेता है, तो वह प्रतीक्षा के आसपास नहीं बैठता है, या तो। यह सिर्फ डेटा को कहीं सुविधाजनक बनाता है और अपने व्यवसाय के बारे में बताता है। इस मामले में, यह ऐसा है जैसे प्रोग्राम बैटन को OS से दूर करता है, और OS बाद में आता है, डेटा के साथ बैटन को जमीन पर गिराता है, और ट्रैक से चलता है। कार्यक्रम हैंड-ऑफ प्राप्त करने के लिए इंतजार कर सकता है या नहीं।
समानता
जब हम किसी फ़ंक्शन को सॉफ़्टवेयर में "async" के रूप में चिह्नित करते हैं, तो अक्सर इसका मतलब है कि हम समानता चाहते हैं । लेकिन याद रखें कि समानता समानता का मतलब नहीं है । फायरफ्लाइज़ एक अच्छा उदाहरण हैं, क्योंकि उन्होंने बहुत समकालिक और अतुल्यकालिक व्यवहार दोनों का प्रदर्शन किया है। जबकि अधिकांश मक्खियां एकसमान में चमकती थीं, कई स्पष्ट रूप से बाकी समूह के साथ धुन से बाहर थीं और अधिक बेतरतीब ढंग से चमकती थीं। मक्खियाँ भले ही एक साथ काम कर रही हों , लेकिन वे सभी सिंक्रनाइज़ नहीं थीं ।
अब जब हम कुछ कोड को "async" के रूप में चिह्नित करते हैं, तो यह मज़ेदार लगता है, क्योंकि इसका अर्थ है कि शेष कोड ऐसा नहीं है जो "सिंक" हो। उस समतल का क्या मतलब है? क्या हमने इस बात पर जोर नहीं दिया कि "सिंक्रोनाइज़ेशन" के लिए दो टैंगो की आवश्यकता थी? लेकिन क्या होगा अगर हम एक ही धागे में कोड निष्पादित करने के बारे में बात कर रहे हैं? इस मामले में, हमें एक कदम वापस लेने और उन राज्यों के बीच राज्यों और बदलावों के अनुक्रम के रूप में एक कार्यक्रम के बारे में सोचने की आवश्यकता है। एक कार्यक्रम में एक बयान एक राज्य संक्रमण का कारण बनता है। हम इसे एक "सूक्ष्म प्रक्रिया" के रूप में सोच सकते हैं जो बयान के साथ शुरू और बंद हो जाता है। भाषा द्वारा परिभाषित अनुक्रम बिंदु वास्तव में, इन "सूक्ष्म प्रक्रियाओं" के सिंक्रनाइज़ेशन बिंदु हैं। और इस प्रकार, हम एक एकल-सूत्र को देख सकते हैं,
प्रोग्रामिंग भाषा की अखंडता गारंटी देती है कि राज्य अद्यतन बयानों में हस्तक्षेप नहीं करते हैं, और अनुक्रम बिंदु उन सीमाओं को परिभाषित करते हैं, जिनके लिए संकलक को पर्यवेक्षित अनुकूलन करने की अनुमति नहीं है। उदाहरण के लिए, किसी कथन के भीतर अभिव्यक्तियों के मूल्यांकन का क्रम अपरिभाषित या अधोमानक हो सकता है, जिससे संकलक को कई प्रकार से कथन का अनुकूलन करने की स्वतंत्रता मिल सकती है। लेकिन जब तक अगला बयान शुरू नहीं हो जाता, तब तक कार्यक्रम एक अच्छी तरह से परिभाषित स्थिति में होना चाहिए, अगर पीएल खुद ही ध्वनि है।
अब तक, यह स्पष्ट होना चाहिए कि हम "async" से क्या मतलब है। इसका सीधा मतलब यह है कि कोड के एक ब्लॉक के भीतर सिंक्रोनाइज्ड के निहित अनुबंध को एसिंक्स ब्लॉक के लिए छूट दी गई है। यह क्रमिक रूप से अनुक्रमिक (ly सुसंगत, तुल्यकालिक) संकलन मॉडल द्वारा निहित सुरक्षा की गारंटी के बिना, कार्यक्रम की स्थिति को स्वतंत्र रूप से अपडेट करने की अनुमति है। बेशक, इसका मतलब है कि हमें विशेष ध्यान रखने की आवश्यकता है कि हम असंगति के साथ कार्यक्रम की स्थिति को नष्ट न करें। इसका आम तौर पर अर्थ है कि हम एस्किसे ब्लॉक के साथ समन्वय करने के लिए सीमित, स्पष्ट सिंक्रोनाइज़ का परिचय देते हैं । ध्यान दें कि इसका मतलब है कि async ब्लॉक अलग-अलग समय में अतुल्यकालिक और तुल्यकालिक दोनों हो सकता है! लेकिन उस सिंक्रनाइज़ेशन को याद करना केवल एक सिंक पॉइंट के अस्तित्व को इंगित करता है, हमें इस धारणा को स्वीकार करने में कोई परेशानी नहीं होनी चाहिए।