प्रोग्रामिंग भाषाएँ स्वचालित रूप से सिंक्रोनस / एसिंक्रोनस समस्या का प्रबंधन क्यों नहीं करती हैं?


27

मुझे इस बारे में कई संसाधन नहीं मिले हैं: मैं सोच रहा था कि क्या यह संभव है / एक अच्छा विचार है जो अतुल्यकालिक कोड को समकालिक तरीके से लिखने में सक्षम हो।

उदाहरण के लिए, यहां कुछ जावास्क्रिप्ट कोड हैं जो डेटाबेस में संग्रहीत उपयोगकर्ताओं की संख्या को पुनः प्राप्त करता है (एक अतुल्यकालिक ऑपरेशन):

getNbOfUsers(function (nbOfUsers) { console.log(nbOfUsers) });

इस तरह से कुछ लिखना संभव होगा:

const nbOfUsers = getNbOfUsers();
console.log(getNbOfUsers);

और इसलिए संकलक स्वचालित रूप से प्रतिक्रिया की प्रतीक्षा करने और फिर निष्पादित करने का ध्यान रखेगा console.log। यह हमेशा अतुल्यकालिक संचालन के पूरा होने का इंतजार करेगा जब परिणाम कहीं और उपयोग किया जाना होगा। हम कॉलबैक वादों, एसिंक्स / वेट या जो भी हो, का इतना कम उपयोग करेंगे, और कभी भी चिंता नहीं करनी होगी कि ऑपरेशन का परिणाम तुरंत उपलब्ध है या नहीं।

त्रुटियां अभी भी प्रबंधनीय होंगी ( स्विफ्ट भाषा nbOfUsersमें वैकल्पिक जैसे प्रयास / कैच या कुछ का उपयोग करके एक पूर्णांक या एक त्रुटि प्राप्त हुई?) ।

क्या यह संभव है? यह एक भयानक विचार / एक स्वप्नलोक हो सकता है ... मुझे नहीं पता।


58
मैं वास्तव में आपके प्रश्न को नहीं समझता। यदि आप "हमेशा एसिंक्रोनस ऑपरेशन की प्रतीक्षा करते हैं", तो यह एसिंक्रोनस ऑपरेशन नहीं है, यह एक सिंक्रोनस ऑपरेशन है। क्या आप स्पष्ट कर सकते हो? हो सकता है कि आप जिस प्रकार के व्यवहार की तलाश कर रहे हैं उसका एक विवरण दें? इसके अलावा, "आप इसके बारे में क्या सोचते हैं" सॉफ्टवेयर इंजीनियरिंग पर ऑफ-टॉपिक है । आपको एक ठोस समस्या के संदर्भ में अपना प्रश्न तैयार करने की आवश्यकता है, जिसमें एक एकल, अस्पष्ट, विहित, उद्देश्यपूर्ण सही उत्तर हो।
जोर्ज डब्ल्यू मित्तग

4
@ JörgWMittag मैं एक काल्पनिक सी # की कल्पना करता हूं, जो इसे बदलने के लिए स्पष्ट रूप से awaitसाTask<T>T
कैलथ

6
आप जो प्रस्ताव करते हैं वह उल्लेखनीय नहीं है। यह तय करने के लिए संकलक तक नहीं है कि आप परिणाम का इंतजार करना चाहते हैं या शायद आग और भूल गए हैं। या पृष्ठभूमि में चलाएं और बाद में इंतजार करें। अपने आप को इस तरह सीमित क्यों करें?
अजीब

5
हाँ, यह एक भयानक विचार है। बस उपयोग async/ awaitबजाय, जो निष्पादन के async भागों को स्पष्ट करता है।
बरगी

5
जब आप कहते हैं कि दो चीजें समवर्ती रूप से होती हैं, तो आप कह रहे हैं कि यह ठीक है कि ये चीजें किसी भी क्रम में होती हैं। यदि आपके कोड में यह स्पष्ट करने का कोई तरीका नहीं है कि क्या री-ऑर्डर आपके कोड की अपेक्षाओं को नहीं तोड़ेंगे, तो यह उन्हें समवर्ती नहीं बना सकता है।
राब

जवाबों:


65

Async / प्रतीक्षारत वह स्वचालित प्रबंधन है जिसे आप प्रस्तावित करते हैं, दो अतिरिक्त खोजशब्दों के साथ। वे महत्वपूर्ण क्यों हैं? एक तरफ पीछे संगतता से?

  • स्पष्ट बिंदुओं के बिना जहां एक कोरटाइन को निलंबित और फिर से शुरू किया जा सकता है, हमें यह पता लगाने के लिए एक प्रकार की प्रणाली की आवश्यकता होगी जहां एक उचित मूल्य का इंतजार किया जाना चाहिए। कई प्रोग्रामिंग भाषाओं में इस प्रकार की प्रणाली नहीं होती है।

  • मूल्य का स्पष्ट रूप से इंतजार करते हुए, हम प्रथम श्रेणी की वस्तुओं के रूप में आसन्न मूल्यों को भी पारित कर सकते हैं: वादे। उच्च-ऑर्डर कोड लिखते समय यह सुपर उपयोगी हो सकता है।

  • भाषा के निष्पादन मॉडल के लिए Async कोड का बहुत गहरा प्रभाव है, भाषा में अपवादों की अनुपस्थिति या उपस्थिति के समान। विशेष रूप से, एक async फ़ंक्शन केवल async फ़ंक्शन द्वारा प्रतीक्षा की जा सकती है। यह सभी कॉलिंग फ़ंक्शन को प्रभावित करता है! लेकिन क्या होगा अगर हम इस निर्भरता श्रृंखला के अंत में एक फ़ंक्शन को नॉन-असिंक से बदलकर एस्किंस में बदल दें? यह एक पश्चगामी-असंगत परिवर्तन होगा ... जब तक कि सभी फ़ंक्शन समान नहीं हैं और प्रत्येक फ़ंक्शन कॉल डिफ़ॉल्ट रूप से प्रतीक्षित है।

    और यह बहुत अवांछनीय है क्योंकि इसमें बहुत खराब प्रदर्शन निहितार्थ हैं। आप केवल सस्ते मूल्यों को वापस करने में सक्षम नहीं होंगे। प्रत्येक फ़ंक्शन कॉल बहुत अधिक महंगा हो जाएगा।

Async बहुत अच्छा है, लेकिन कुछ प्रकार के निहितार्थ Async वास्तविकता में काम नहीं करेंगे।

हास्केल जैसी शुद्ध कार्यात्मक भाषाओं में थोड़ी बच निकलती है क्योंकि निष्पादन आदेश काफी हद तक अनिर्दिष्ट और अप्रमाणित है। या अलग तरीके से बनाए गए: संचालन के किसी भी विशिष्ट क्रम को स्पष्ट रूप से एन्कोड किया जाना चाहिए। यह वास्तविक दुनिया के कार्यक्रमों के लिए बोझिल हो सकता है, विशेष रूप से उन I / O- भारी कार्यक्रमों के लिए जिनके लिए async कोड बहुत अच्छा है।


2
आप एक प्रकार की प्रणाली की आवश्यकता नहीं है। उदाहरण के लिए ECMAScript, Smalltalk, Self, Newspeak, Io, Ioke, Seph में पारदर्शी फ्यूचर्स, बिना tyoe सिस्टम या भाषा समर्थन के आसानी से लागू किया जा सकता है। स्मॉलटाक और इसके वंशजों में, कोई वस्तु पारदर्शी रूप से अपनी पहचान बदल सकती है, ईसीएमएस्क्रिप्ट में, यह पारदर्शी रूप से अपना आकार बदल सकती है। आपको केवल वायदा को पारदर्शी बनाने की आवश्यकता है, अतुल्यकालिक के लिए भाषा समर्थन की आवश्यकता नहीं है।
जोर्ज डब्ल्यू मित्तग

6
@ JörgWMittag मैं समझता हूं कि आप क्या कह रहे हैं और कैसे काम कर सकते हैं, लेकिन एक प्रकार की प्रणाली के बिना पारदर्शी वायदा एक साथ प्रथम श्रेणी के वायदा करना मुश्किल है, नहीं? मुझे यह चुनने के लिए किसी तरह की आवश्यकता होगी कि क्या मैं भविष्य या भविष्य के मूल्य पर संदेश भेजना चाहता हूं, अधिमानतः कुछ बेहतर है someValue ifItIsAFuture [self| self messageIWantToSend]क्योंकि यह सामान्य कोड के साथ एकीकृत करने के लिए मुश्किल है।
अमोन

8
@amon "मैं अपना async कोड लिख सकता हूं क्योंकि वादे और वादे मोनाड हैं।" मोनाड वास्तव में यहां आवश्यक नहीं हैं। थ्रो अनिवार्य रूप से सिर्फ वादे हैं। चूंकि हास्केल में लगभग सभी मूल्य बॉक्सिंग हैं, हास्केल में लगभग सभी मूल्य पहले से ही वादे हैं। यही कारण है कि आप parशुद्ध हास्केल कोड में कहीं भी बहुत अधिक टॉस कर सकते हैं और मुफ्त में समानता प्राप्त कर सकते हैं।
डेर्थफेनेक

2
Async / प्रतीक्षारत मुझे निरंतरता की याद दिलाता है।
लेस

3
वास्तव में, अपवाद और एस्कॉन / वेट दोनों बीजीय प्रभावों के उदाहरण हैं ।
एलेक्स रिंकिंग

21

आप जो याद कर रहे हैं, वह async ऑपरेशंस का उद्देश्य है: वे आपको अपने प्रतीक्षा समय का उपयोग करने की अनुमति देते हैं!

यदि आप एक async कार्रवाई को चालू करते हैं, जैसे कि सर्वर से कुछ संसाधन का अनुरोध करना, तो संक्षेप में और तुरंत उत्तर की प्रतीक्षा में एक तुल्यकालिक ऑपरेशन में, आपका धागा प्रतीक्षा समय के साथ और कुछ नहीं कर सकता है । यदि सर्वर को जवाब देने में 10 मिलीसेकंड लगते हैं, तो बेकार में लगभग 30 मिलियन सीपीयू चक्र जाते हैं। प्रतिक्रिया की विलंबता अनुरोध के लिए निष्पादन समय बन जाती है।

केवल यही कारण है कि प्रोग्रामर ने एसिंक्स संचालन का आविष्कार किया, यह अन्य उपयोगी संगणना के पीछे स्वाभाविक रूप से लंबे समय तक चलने वाले कार्यों की विलंबता को छिपाने के लिए है । यदि आप प्रतीक्षा समय को उपयोगी कार्य से भर सकते हैं, तो CPU समय की बचत होगी। यदि आप नहीं कर सकते हैं, ठीक है, ऑपरेशन से कुछ भी नहीं खो दिया है।

इसलिए, मैं आपके द्वारा प्रदान की जाने वाली async संक्रियाओं को अपनाने की सलाह देता हूं। वे वहाँ आप समय बचाने के लिए कर रहे हैं।


मैं एक कार्यात्मक भाषा के बारे में सोच रहा था, जहां संचालन अवरुद्ध नहीं हो रहा है, इसलिए भले ही इसमें एक सिंक्रोनस सिंटैक्स हो, लंबे समय तक चलने वाली गणना थ्रेड को ब्लॉक नहीं करेगी
Cinn

6
@ मुझे ऐसा नहीं लगा कि प्रश्न में, और प्रश्न में उदाहरण जावास्क्रिप्ट है, जिसमें यह सुविधा नहीं है। हालांकि, आम तौर पर यह एक संकलक के लिए समानांतर के लिए सार्थक अवसरों को खोजने के लिए कठिन है जैसा कि आप वर्णन करते हैं: इस तरह की सुविधा के सार्थक शोषण से प्रोग्रामर को स्पष्ट रूप से सोचने की आवश्यकता होगी कि वे एक लंबी विलंबता कॉल के बाद सही क्या कहते हैं। यदि आप प्रोग्रामर पर इस आवश्यकता से बचने के लिए रनटाइम को काफी स्मार्ट बनाते हैं, तो आपका रनटाइम संभवतः प्रदर्शन बचत को खाएगा क्योंकि इसे फ़ंक्शन कॉल में आक्रामक रूप से समानांतर करने की आवश्यकता होगी।
सेमीस्टर

2
सभी कंप्यूटर एक ही गति से प्रतीक्षा करते हैं।
बॉब जार्विस -

2
@ याकूब जार्विस हाँ। लेकिन वे इस बात में भिन्न हैं कि वे प्रतीक्षा के समय में कितना काम कर सकते थे ...
सेमीस्टर

13

कुछ करते हैं।

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

उस ने कहा, यह स्पष्ट रूप से हर जगह करने के लिए एक अच्छा विचार नहीं है। एक आम असफलता लूप में async कॉल कर रही है, प्रभावी रूप से उनके निष्पादन को क्रमबद्ध कर रही है। एसिंक्रोनस कॉल होने का अर्थ यह हो सकता है कि उस तरह की त्रुटि अस्पष्ट हो। इसके अलावा, यदि आप Task<T>(या आपकी भाषा के समतुल्य) से निहित ज़बरदस्ती का समर्थन करते हैं T, तो यह आपके टाइपसीचर और त्रुटि रिपोर्टिंग में थोड़ी जटिलता / लागत जोड़ सकता है जब यह स्पष्ट नहीं होता है कि प्रोग्रामर वास्तव में दोनों में से कौन चाहता है।

लेकिन वे दुर्गम समस्याएं नहीं हैं। यदि आप उस व्यवहार का समर्थन करना चाहते हैं जो आप लगभग निश्चित रूप से कर सकते हैं, हालांकि व्यापार-नापसंद होगा।


1
मुझे लगता है कि एक विचार सब कुछ को async फ़ंक्शंस में लपेटने के लिए हो सकता है, सिंक्रोनस फ़ंक्शंस बस तुरंत हल हो जाएंगे और हमें सभी को संभालने के लिए एक तरह का मिलेगा (संपादित करें: @amon ने बताया कि यह एक बुरा विचार क्यों है ...)
Cinn

8
क्या आप " कुछ करते हैं " के लिए कुछ उदाहरण दे सकते हैं , कृपया?
बरगी

2
अतुल्यकालिक प्रोग्रामिंग किसी भी तरह से नया नहीं है, यह सिर्फ इतना है कि आजकल लोगों को इससे अधिक बार निपटना पड़ता है।
घन

1
@ क्यूबिक - यह एक भाषा विशेषता है जहाँ तक मुझे पता है। इससे पहले कि यह सिर्फ (अजीब) उपयोगकर्ता कार्य था।
तेलस्तीन

12

ऐसी भाषाएँ हैं जो ऐसा करती हैं। लेकिन, वास्तव में इसकी बहुत आवश्यकता नहीं है, क्योंकि इसे आसानी से मौजूदा भाषा सुविधाओं के साथ पूरा किया जा सकता है।

जब तक आपके पास अतुल्यकालिक को व्यक्त करने का कोई तरीका है, तब तक आप फ्यूचर्स या प्रोमिस को विशुद्ध रूप से एक पुस्तकालय सुविधा के रूप में लागू कर सकते हैं, आपको किसी विशेष भाषा सुविधाओं की आवश्यकता नहीं है। और जब तक आपके पास Transparent Proxies व्यक्त करने के कुछ हैं , आप दोनों सुविधाओं को एक साथ रख सकते हैं और आपके पास Transparent Futures है

उदाहरण के लिए, स्मॉलटाक और उसके वंशजों में, एक वस्तु अपनी पहचान बदल सकती है, यह वस्तुतः "एक अलग वस्तु" बन सकती है (और वास्तव में ऐसा करने वाली विधि कहा जाता है Object>>become:)।

एक लंबे समय तक चलने वाले संगणना की कल्पना कीजिए जो एक रिटर्न देता है Future<Int>। यह Future<Int>सभी तरीकों के समान है Int, अलग-अलग कार्यान्वयन के अलावा। Future<Int>की +विधि दूसरा नंबर जोड़ नहीं है और परिणाम लौटने के लिए, यह एक नया रिटर्न Future<Int>जो गणना गिर्द घूमती है। इत्यादि इत्यादि। तरीके कि समझदारी से एक वापस लौट कर लागू नहीं किया जा सकता है Future<Int>, के बजाय स्वचालित रूप से awaitपरिणाम है, और फिर कहते हैं self become: result., जो वर्तमान में क्रियान्वित वस्तु कर देगा ( selfअर्थात Future<Int>) का शाब्दिक बन resultवस्तु यानी अब से वस्तु संदर्भ पर कि होने के लिए एक प्रयोग किया जाता है, Future<Int>है अब Intहर जगह, क्लाइंट के लिए पूरी तरह से पारदर्शी।

कोई विशेष अतुल्यकालिक-संबंधित भाषा सुविधाओं की आवश्यकता नहीं है।


ठीक है, लेकिन यह है कि दोनों अगर समस्या है Future<T>और Tकुछ सामान्य इंटरफ़ेस का हिस्सा है और मुझे लगता है कि इंटरफ़ेस से कार्यक्षमता का उपयोग। क्या इसका becomeपरिणाम होना चाहिए और फिर कार्यक्षमता का उपयोग करना चाहिए , या नहीं? मैं समानता ऑपरेटर या टू-स्ट्रिंग डिबगिंग प्रतिनिधित्व जैसी चीजों के बारे में सोच रहा हूं।
अमोन

मैं समझता हूं कि इसमें कोई विशेषताएं नहीं हैं, बात यह है कि हमारे पास तुरंत हल करने वाली संगणनाएं और लंबे समय तक चलने वाली संगणनाएं लिखने के लिए अलग-अलग वाक्यविन्यास हैं, और उसके बाद हम परिणामों को अन्य प्रयोजनों के लिए उसी तरह उपयोग करेंगे। मैं सोच रहा था कि क्या हम एक वाक्यविन्यास कर सकते हैं जो पारदर्शी रूप से दोनों को संभाल सकता है, जिससे यह अधिक पठनीय हो सकता है और इसलिए प्रोग्रामर को इसे संभालना नहीं पड़ता है। करने की तरह a + b, दोनों पूर्णांक, कोई फर्क नहीं a + bपड़ता अगर ए और बी तुरंत या बाद में उपलब्ध हैं, तो हम सिर्फ लिखते हैं (करने के लिए संभव Int + Future<Int>)
Cinn

@Cinn: हाँ, आप कर सकते हैं कि पारदर्शी वायदा के साथ, और आपको ऐसा करने के लिए किसी विशेष भाषा सुविधाओं की आवश्यकता नहीं है। आप इसे पहले से मौजूद फीचर्स जैसे कि स्मालटाक, सेल्फ, न्यूजक, अस, कोरज, Io, इओक, सेप, इस्मैस्क्रिप्ट और जाहिर तौर पर, जैसा कि मैंने अभी पढ़ा है, पायथन को इस्तेमाल करके इसे लागू कर सकते हैं।
जोर्ग डब्ल्यू मित्तग

3
@amon: पारदर्शी वायदा का विचार यह है कि आप नहीं जानते कि यह भविष्य है। आपके दृष्टिकोण से, आपके बीच के दृष्टिकोण से कोई समान इंटरफ़ेस नहीं है Future<T>और Tक्योंकि , केवल कोई नहींFuture<T> है T। अब, यह कैसे कुशल बनाने के लिए चारों ओर इंजीनियरिंग चुनौतियों का एक बहुत कुछ है, जो संचालन बनाम गैर-अवरोधक, आदि अवरुद्ध होना चाहिए, लेकिन यह वास्तव में स्वतंत्र है कि आप इसे भाषा के रूप में करते हैं या पुस्तकालय की सुविधा के रूप में। पारदर्शिता प्रश्न में ओपी द्वारा निर्धारित एक आवश्यकता थी, मैं यह तर्क नहीं दूंगा कि यह कठिन है और इसका कोई मतलब नहीं है।
जोर्ग डब्ल्यू मित्तग

3
@ जोर्ग ऐसा लगता है कि यह किसी भी चीज़ में समस्याग्रस्त होगा, लेकिन कार्यात्मक भाषाएं क्योंकि आपके पास यह जानने का कोई तरीका नहीं है कि कोड वास्तव में उस मॉडल में कब निष्पादित किया गया है। आमतौर पर हास्केल कहने में ठीक काम करता है, लेकिन मैं यह नहीं देख सकता कि यह अधिक प्रक्रियात्मक भाषाओं में कैसे काम करेगा (और यहां तक ​​कि हास्केल में, यदि आप प्रदर्शन के बारे में परवाह करते हैं तो आपको कभी-कभी निष्पादन को मजबूर करना पड़ता है और अंतर्निहित मॉडल को समझना पड़ता है)। एक दिलचस्प विचार फिर भी।
वू

7

वे करते हैं (अच्छी तरह से, उनमें से ज्यादातर)। जिस सुविधा के लिए आप देख रहे हैं उसे थ्रेड्स कहा जाता है ।

हालांकि धागे की अपनी समस्याएं हैं:

  1. क्योंकि कोड को किसी भी बिंदु पर निलंबित किया जा सकता है , आप कभी भी यह नहीं मान सकते हैं कि चीजें "खुद से" नहीं बदलेंगी। थ्रेड्स के साथ प्रोग्रामिंग करते समय, आप यह सोचने में बहुत समय बर्बाद करते हैं कि आपके प्रोग्राम को चीजों को बदलने से कैसे निपटना चाहिए।

    एक गेम सर्वर की कल्पना करें कि एक खिलाड़ी दूसरे खिलाड़ी पर हमला कर रहा है। कुछ इस तरह:

    if (playerInMeleeRange(attacker, victim)) {
        const damage = calculateAttackDamage(attacker, victim);
        if (victim.health <= damage) {
    
            // attacker gets whatever the victim was carrying as loot
            const loot = victim.getInventoryItems();
            attacker.addInventoryItems(loot);
            victim.removeInventoryItems(loot);
    
            victim.sendMessage("${attacker} hits you with a ${attacker.currentWeapon} and you die!");
            victim.setDead();
        } else {
            victim.health -= damage;
            victim.sendMessage("${attacker} hits you with a ${attacker.currentWeapon}!");
        }
        attacker.markAsKiller();
    }
    

    तीन महीने बाद, एक खिलाड़ी को पता चलता है कि मारे जाने से और attacker.addInventoryItemsभागते समय ठीक से लॉग इन करने पर , फिर victim.removeInventoryItemsविफल हो जाएगा, वह अपनी वस्तुओं को रख सकता है और हमलावर को अपने सामानों की एक प्रति भी मिलती है। वह कई बार ऐसा करता है, जिससे एक लाख टन सोना पतली हवा से बाहर निकलता है और खेल की अर्थव्यवस्था चरमरा जाती है।

    वैकल्पिक रूप से, हमलावर लॉग आउट कर सकता है जबकि खेल पीड़ित को एक संदेश भेज रहा है, और उसे अपने सिर के ऊपर एक "कातिल" टैग नहीं मिलेगा, इसलिए उसका अगला शिकार उससे दूर नहीं चलेगा।

  2. क्योंकि कोड को किसी भी बिंदु पर निलंबित किया जा सकता है , आपको डेटा संरचनाओं में हेरफेर करते समय हर जगह ताले का उपयोग करने की आवश्यकता होती है। मैंने ऊपर एक उदाहरण दिया, जिसमें एक खेल में स्पष्ट परिणाम हैं, लेकिन यह अधिक सूक्ष्म हो सकता है। लिंक की गई सूची की शुरुआत में एक आइटम जोड़ने पर विचार करें:

    newItem.nextItem = list.firstItem;
    list.firstItem = newItem;
    

    यह एक समस्या नहीं है यदि आप कहते हैं कि थ्रेड को केवल I / O करते समय निलंबित किया जा सकता है, और किसी भी बिंदु पर नहीं। लेकिन मुझे यकीन है कि आप ऐसी स्थिति की कल्पना कर सकते हैं जहाँ I / O ऑपरेशन हो - जैसे लॉगिंग:

    for (player = playerList.firstItem; player != null; player = item.nextPlayer) {
        debugLog("${item.name} is online, they get a gold star");
        // Oops! The player might've logged out while the log message was being written to disk, and now this will throw an exception and the remaining players won't get their gold stars.
        // Or the list might've been rearranged and some players might get two and some players might get none.
        player.addInventoryItem(InventoryItems.GoldStar);
    }
    
  3. क्योंकि कोड को किसी भी बिंदु पर निलंबित किया जा सकता है , इसलिए संभावित रूप से बचाने के लिए बहुत सारे राज्य हो सकते हैं। सिस्टम प्रत्येक थ्रेड को पूरी तरह से अलग स्टैक देकर इससे संबंधित है। लेकिन स्टैक काफी बड़ा है, इसलिए आपके पास 32-बिट प्रोग्राम में लगभग 2000 से अधिक धागे नहीं हो सकते हैं। या आप इसे बहुत छोटा बनाने के जोखिम पर स्टैक आकार को कम कर सकते हैं।


3

यहाँ बहुत सारे उत्तर भ्रामक लगते हैं, क्योंकि जब प्रश्न शाब्दिक रूप से अतुल्यकालिक प्रोग्रामिंग के बारे में पूछ रहा था और गैर-अवरुद्ध आईओ नहीं, तो मुझे नहीं लगता कि हम इस विशेष मामले में दूसरे पर चर्चा किए बिना एक पर चर्चा कर सकते हैं।

जबकि अतुल्यकालिक प्रोग्रामिंग स्वाभाविक है, अच्छी तरह से, अतुल्यकालिक, अतुल्यकालिक प्रोग्रामिंग के raison d'être ज्यादातर कर्नेल थ्रेड्स को अवरुद्ध करने से बचने के लिए है। Node.js कॉलबैक के माध्यम से एसिंक्रोनसिटी का उपयोग करता है या Promiseकिसी ईवेंट लूप से ब्लॉकिंग ऑपरेशन को अनुमति देने के लिए या जावा में नेट्टी कॉलबैक या CompletableFutureएस के माध्यम से एसिंक्रोनसिटी का उपयोग करता है ।

गैर-अवरोधक कोड के लिए अतुल्यकालिकता की आवश्यकता नहीं होती है, हालांकि । यह निर्भर करता है कि आपकी प्रोग्रामिंग भाषा और रनटाइम आपके लिए कितना तैयार है।

गो, एर्लैंग, और हास्केल / जीएचसी आपके लिए इसे संभाल सकते हैं। आप कुछ लिख सकते हैं var response = http.get('example.com/test')और प्रतिक्रिया के लिए प्रतीक्षा करते समय इसे पर्दे के पीछे एक कर्नेल धागा जारी कर सकता है। यह गोरोनाइट्स, एरलंग प्रक्रियाओं द्वारा किया जाता है, या forkIOअवरुद्ध होने पर पर्दे के पीछे कर्नेल थ्रेड्स को जाने देता है, जिससे इसे प्रतिक्रिया की प्रतीक्षा करते समय अन्य चीजों को करने की अनुमति मिलती है।

यह सच है कि भाषा वास्तव में आपके लिए एसिंक्रोनसिटी को संभाल नहीं सकती है, लेकिन कुछ अमूर्तताएं आपको दूसरों की तुलना में आगे बढ़ने देती हैं जैसे कि अविभाजित निरंतरता या असममित कोरटाइन। हालांकि, अतुल्यकालिक कोड, ब्लॉकिंग सिस्टम कॉल का प्राथमिक कारण, बिल्कुल डेवलपर से दूर हो सकता है।

Node.js और Java अतुल्यकालिक गैर-अवरोधक कोड का समर्थन करते हैं , जबकि Go और Erlang तुल्यकालिक गैर-अवरोधक कोड का समर्थन करते हैं । वे दोनों अलग-अलग ट्रेडऑफ़ के साथ मान्य दृष्टिकोण हैं।

मेरे बजाय व्यक्तिपरक तर्क यह है कि डेवलपर की ओर से गैर-अवरोधक का प्रबंधन करने वाले रनटाइम्स के खिलाफ बहस करने वाले लोग शुरुआती नामों में कचरा संग्रह के खिलाफ बहस करने वाले हैं। हां, यह एक लागत लगाता है (इस मामले में मुख्य रूप से अधिक मेमोरी), लेकिन यह विकास और डिबगिंग को आसान बनाता है, और कोडबेस को अधिक मजबूत बनाता है।

मैं व्यक्तिगत रूप से तर्क देता हूं कि अतुल्यकालिक गैर-अवरोधक कोड को भविष्य में सिस्टम प्रोग्रामिंग के लिए आरक्षित किया जाना चाहिए और अधिक आधुनिक प्रौद्योगिकी स्टैक को अनुप्रयोग विकास के लिए सिंक्रोनस गैर-ब्लॉकिंग रनटाइम से माइग्रेट करना चाहिए ।


1
यह वास्तव में एक दिलचस्प जवाब था! लेकिन मुझे यकीन नहीं है कि मैं "तुल्यकालिक" और "अतुल्यकालिक" गैर-अवरोधक कोड के बीच के अंतर को समझता हूं। मेरे लिए, सिंक्रोनस नॉन-ब्लॉकिंग कोड का मतलब सी फ़ंक्शन की तरह कुछ है waitpid(..., WNOHANG)जो विफल हो जाता है अगर इसे ब्लॉक करना होगा। या यहाँ "तुल्यकालिक" का मतलब है "कोई प्रोग्रामर-दृश्यमान कॉलबैक / राज्य मशीन / इवेंट लूप नहीं हैं"? लेकिन आपके उदाहरण के लिए, मुझे अभी भी स्पष्ट रूप से एक चैनल से पढ़कर गोरोइन के परिणाम का इंतजार करना होगा, नहीं? JS / C # / पायथन में async / wait की तुलना में यह कैसे कम है?
आमोन

1
डेवलपर के सामने आए प्रोग्रामिंग मॉडल पर चर्चा करने के लिए मैं "एसिंक्रोनस" और "सिंक्रोनस" का उपयोग करता हूं और कर्नेल थ्रेड को ब्लॉक करने के बारे में चर्चा करने के लिए "ब्लॉकिंग" और "नॉन-ब्लॉकिंग" करता हूं, इसके बावजूद कुछ उपयोगी नहीं हो सकता। अन्य संगणनाएँ जिन्हें करने की आवश्यकता होती है और एक अतिरिक्त तार्किक प्रोसेसर होता है जो इसका उपयोग कर सकता है। ठीक है, एक goroutine अंतर्निहित धागे को अवरुद्ध किए बिना एक परिणाम के लिए चारों ओर इंतजार कर सकता है, लेकिन एक अन्य गोरोइनट चैनल पर इसके साथ संवाद कर सकता है अगर यह चाहता है। हालांकि गैर-अवरुद्ध सॉकेट के लिए प्रतीक्षा करने के लिए गोरोइन को सीधे एक चैनल का उपयोग करने की आवश्यकता नहीं है ।
लुई जैकमैन

हम्म ठीक है, मैं अब आपका भेद समझता हूँ। जहाँ मैं डेटा प्रबंधन के बारे में अधिक चिंतित हूं- और कोरटाइन के बीच नियंत्रण-प्रवाह, आप मुख्य कर्नेल थ्रेड को कभी भी अवरुद्ध नहीं करने के बारे में अधिक चिंतित हैं। मुझे यकीन नहीं है कि गो या हास्केल को इस संबंध में सी ++ या जावा पर कोई फायदा नहीं है क्योंकि वे भी बैकग्राउंड थ्रेड्स को किक कर सकते हैं, ऐसा करने के लिए बस एक टैड अधिक कोड की आवश्यकता होती है।
आमोन

@LouisJackman सिस्टम प्रोग्रामिंग के लिए async नॉन-ब्लॉकिंग के बारे में आपके अंतिम कथन पर थोड़ा विस्तार कर सकता है। Async नॉन-ब्लॉकिंग अप्रोच के नियम क्या हैं?
सूर्यप्रकाश

@sunprophit अतुल्यकालिक गैर-अवरोधक बस एक संकलक परिवर्तन (आमतौर पर async / प्रतीक्षारत) है, जबकि सिंक्रोनस गैर-अवरोधक को कुछ जटिल संयोजन हेरफेर की तरह रनटाइम समर्थन की आवश्यकता होती है, फ़ंक्शन कॉल पर उपज बिंदु सम्मिलित करते हैं (जो इनलाइन के साथ टकरा सकते हैं), ट्रैकिंग " कटौती "(बीईएएम की तरह वीएम की आवश्यकता होती है), आदि कचरा संग्रह की तरह, यह उपयोग और मजबूती में आसानी के लिए कम रनटाइम जटिलता का व्यापार कर रहा है। C, C ++, और Rust जैसी सिस्टम भाषाएं अपने लक्षित डोमेन के कारण इस तरह की बड़ी रनटाइम सुविधाओं से बचती हैं, इसलिए अतुल्यकालिक गैर-अवरोधन वहां अधिक समझ में आता है।
लुई जैकमैन

2

अगर मैं आपको सही पढ़ रहा हूं, तो आप एक तुल्यकालिक प्रोग्रामिंग मॉडल के लिए पूछ रहे हैं, लेकिन एक उच्च निष्पादन कार्यान्वयन। यदि यह सही है, तो यह पहले से ही हरे धागे या उदाहरण के लिए एर्लांग या हास्केल की प्रक्रियाओं के रूप में हमारे पास उपलब्ध है। तो हाँ, यह एक उत्कृष्ट विचार है, लेकिन मौजूदा भाषाओं में रेट्रोफ़िटिंग हमेशा उतनी चिकनी नहीं हो सकती जितनी आप चाहते हैं।


2

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

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

उच्चतम स्तर की भाषा अंग्रेजी बोल रही होगी, और यह जानने के लिए कि आपको वास्तव में क्या करना है, यह जानने के लिए कार्य करने वाले की क्षमता पर निर्भर होना चाहिए। (स्टार ट्रेक में कंप्यूटर के बारे में सोचें, या एलेक्सा के बारे में कुछ पूछें।) हम उससे बहुत दूर हैं, लेकिन करीब करीब आ रहे हैं, और मेरी अपेक्षा यह है कि भाषा / संकलक इतना मजबूत, इरादा कोड उत्पन्न करने के लिए अधिक हो सकता है, जहां तक ​​जाने के बिना। एअर इंडिया की जरूरत है।

एक तरफ, नए दृश्य भाषाएं हैं, जैसे स्क्रैच, जो ऐसा करते हैं और सभी वाक्यविन्यास तकनीकीताओं से प्रभावित नहीं होते हैं। निश्चित रूप से, बहुत सारे पीछे के काम चल रहे हैं, इसलिए प्रोग्रामर को इसके बारे में चिंता करने की ज़रूरत नहीं है। उस ने कहा, मैं स्क्रैच में बिजनेस क्लास सॉफ्टवेयर नहीं लिख रहा हूं, इसलिए, आपकी तरह, मुझे भी यही उम्मीद है कि परिपक्व प्रोग्रामिंग भाषाओं के लिए स्वचालित रूप से सिंक्रोनस / एसिंक्रोनस समस्या का प्रबंधन करने का समय आ गया है।


1

आपके द्वारा वर्णित समस्या दो-गुना है।

  • आपके द्वारा लिखा गया कार्यक्रम बाहर से देखने पर अतुल्यकालिक रूप से एक पूरे के रूप में व्यवहार करना चाहिए ।
  • यह कॉल साइट पर दिखाई नहीं देना चाहिए कि क्या कोई फ़ंक्शन कॉल संभावित रूप से नियंत्रण देता है या नहीं।

इसे प्राप्त करने के कुछ तरीके हैं, लेकिन वे मूल रूप से उबालते हैं

  1. कई धागे (अमूर्त के कुछ स्तर पर)
  2. भाषा के स्तर पर कई प्रकार के कार्य होते हैं, जिन्हें सभी इस तरह कहते हैं foo(4, 7, bar, quux)

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

(२) दिलचस्प है। इसे न्याय करने के लिए हमें परिचय और उन्मूलन रूपों के बारे में बात करने की आवश्यकता है।

मैं यह दिखाने जा रहा हूं कि क्यों awaitजावास्क्रिप्ट को जावास्क्रिप्ट की तरह किसी भाषा में पीछे-संगत तरीके से नहीं जोड़ा जा सकता है। मूल विचार यह है कि उपयोगकर्ता को वादों को उजागर करने और तुल्यकालिक और अतुल्यकालिक संदर्भों के बीच अंतर होने से, जावास्क्रिप्ट ने एक कार्यान्वयन विवरण लीक किया है जो तुल्यकालिक और अतुल्यकालिक कार्यों को समान रूप से संभालने से रोकता है। यह भी तथ्य है कि आप awaitएक async फ़ंक्शन बॉडी के बाहर एक वादा नहीं कर सकते । ये डिज़ाइन विकल्प "कॉल करने वाले के लिए अतुल्यकालिकता को अदृश्य बनाने" के साथ असंगत हैं।

आप एक लैम्ब्डा का उपयोग करके एक तुल्यकालिक फ़ंक्शन का परिचय कर सकते हैं और इसे फ़ंक्शन कॉल के साथ समाप्त कर सकते हैं।

सिंक्रोनस फ़ंक्शन परिचय:

((x) => {return x + x;})

तुल्यकालिक समारोह उन्मूलन:

f(4)

((x) => {return x + x;})(4)

आप इसे अतुल्यकालिक फ़ंक्शन परिचय और उन्मूलन के साथ विपरीत कर सकते हैं।

अतुल्यकालिक फ़ंक्शन परिचय

(async (x) => {return x + x;})

असिंक्रोनस फंक्शन एलिमिनेशन (नोट: केवल एक asyncफंक्शन के अंदर ही मान्य )

await (async (x) => {return x + x;})(4)

यहाँ मूलभूत समस्या यह है कि एक एसिंक्रोनस फ़ंक्शन एक वादा वस्तु का उत्पादन करने वाला एक सिंक्रोनस फ़ंक्शन भी है

यहाँ नोड में एक असिंक्रोनस फ़ंक्शन को कॉल करने का एक उदाहरण है।

> (async (x) => {return x + x;})(4)
Promise { 8 }

आपके पास काल्पनिक रूप से एक भाषा हो सकती है, यहां तक ​​कि एक गतिशील रूप से टाइप किया गया, जहां कॉल साइट पर अतुल्यकालिक और सिंक्रोनस फ़ंक्शन कॉल के बीच का अंतर दिखाई नहीं देता है और संभवतः परिभाषा साइट पर दिखाई नहीं देता है।

इस तरह की भाषा लेना और इसे जावास्क्रिप्ट में कम करना संभव है, आपको बस सभी कार्यों को अतुल्यकालिक रूप से प्रभावी बनाना होगा।


1

गो भाषा के गोरोइटिन, और गो भाषा के चलने के समय के साथ, आप सभी कोड लिख सकते हैं जैसे कि यह सिंक्रोन था। यदि एक गोरोइन में एक ऑपरेशन अवरुद्ध हो जाता है, तो अन्य गोरोइनों में निष्पादन जारी रहता है। और चैनलों के साथ आप आसानी से गोरोइनों के बीच संवाद कर सकते हैं। यह अक्सर जावास्क्रिप्ट की तरह कॉलबैक से आसान है या अन्य भाषाओं में async / प्रतीक्षा में है। कुछ उदाहरणों और स्पष्टीकरण के लिए https://tour.golang.org/concurrency/1 देखें ।

इसके अलावा, मेरे पास इसके साथ कोई व्यक्तिगत अनुभव नहीं है, लेकिन मैंने सुना है कि एर्लांग में भी ऐसी ही सुविधाएं हैं।

तो, हाँ, गो और एर्लैंग जैसी प्रोग्रामिंग भाषाएं हैं, जो समकालिक / अतुल्यकालिक समस्या को हल करती हैं, लेकिन दुर्भाग्य से वे अभी तक बहुत लोकप्रिय नहीं हैं। जैसे-जैसे उन भाषाओं की लोकप्रियता बढ़ती है, शायद वे जो सुविधाएं प्रदान करती हैं, वे अन्य भाषाओं में भी लागू की जाएंगी।


मैंने लगभग कभी भी गो भाषा का उपयोग नहीं किया है, लेकिन ऐसा लगता है कि आप स्पष्ट रूप से घोषणा करते हैं go ..., इसलिए यह समान दिखता है await ...?
Cinn

1
@Cinn वास्तव में, नहीं। आप अपने स्वयं के फाइबर / हरे-धागे के साथ गोरोइन के रूप में किसी भी कॉल को लगा सकते हैं go। और बस किसी भी कॉल के बारे में जो रनटाइम द्वारा एसिंक्रोनस रूप से किया जा सकता है, जो कि इस बीच एक अलग गोरोइन पर स्विच करता है (सहकारी मल्टी-टास्किंग)। आप एक संदेश की प्रतीक्षा कर रहे हैं।
Deduplicator

2
जबकि गोरआउट एक तरह की संगामिति है, मैं उन्हें एक ही बाल्टी में नहीं डालूंगा जैसे कि async / इंतजार: सहकारी कोरआउट नहीं बल्कि स्वचालित रूप से (और preemptively!) अनुसूचित हरे धागे। लेकिन यह स्वचालित रूप से प्रतीक्षा नहीं करता है: गो के समकक्ष awaitएक चैनल से पढ़ रहा है <- ch
अमोन

@amon जहां तक ​​मुझे पता है, रनआउट के दौरान, गोरोइन्ट्स को मूल रूप से देशी थ्रेड्स (सामान्य रूप से केवल सही हार्डवेयर समानता को अधिकतम करने के लिए) पर अनुसूचित किया जाता है, और जो ओएस द्वारा पूर्व निर्धारित हैं।
Deduplicator

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

1

एक बहुत ही महत्वपूर्ण पहलू है जो अभी तक नहीं उठाया गया है: पुनरावृत्ति। यदि आपके पास कोई अन्य कोड (जैसे: इवेंट लूप) है जो async कॉल के दौरान चलता है (और यदि आप नहीं तो आपको async की आवश्यकता क्यों है?), तो कोड प्रोग्राम की स्थिति को प्रभावित कर सकता है। आप कॉलर से एसिंक्स कॉल को छिपा नहीं सकते क्योंकि कॉलर अपने फ़ंक्शन कॉल की अवधि के लिए अप्रभावित रहने के लिए प्रोग्राम स्थिति के कुछ हिस्सों पर निर्भर हो सकता है। उदाहरण:

function foo( obj ) {
    obj.x = 2;
    bar();
    log( "obj.x equals 2: " + obj.x );
}

यदि bar()यह एक async फ़ंक्शन है, तो obj.xनिष्पादन के दौरान इसे बदलना संभव हो सकता है । यह बिना किसी संकेत के अप्रत्याशित होगा कि बार async है और यह प्रभाव संभव है। एकमात्र विकल्प यह होगा कि हर संभावित फ़ंक्शन / पद्धति पर एस्किंस होने का संदेह करें और प्रत्येक फ़ंक्शन कॉल के बाद किसी भी गैर-स्थानीय स्थिति को फिर से जांचें। यह सूक्ष्म कीड़े के लिए प्रवण होता है और यह संभव भी नहीं हो सकता है यदि कुछ गैर-स्थानीय राज्य को कार्यों के माध्यम से लाया जाता है। इस वजह से, प्रोग्रामर को इस बात की जानकारी होनी चाहिए कि कौन से कार्यों में अप्रत्याशित तरीके से प्रोग्राम स्टेट को बदलने की क्षमता है:

async function foo( obj ) {
    obj.x = 2;
    await bar();
    log( "obj.x equals 2: " + obj.x );
}

अब यह स्पष्ट रूप से दिखाई दे रहा है कि bar()यह एक async फ़ंक्शन है, और इसे संभालने का सही तरीका obj.xइसके बाद के अपेक्षित मूल्य की फिर से जाँच करना और जो भी बदलाव हुए हैं, उनसे निपटना है।

जैसा कि पहले से ही अन्य उत्तरों के अनुसार, हास्केल जैसी शुद्ध कार्यात्मक भाषाएं किसी भी साझा / वैश्विक राज्य की आवश्यकता से पूरी तरह से बचकर उस प्रभाव से बच सकती हैं। मेरे पास कार्यात्मक भाषाओं के साथ अधिक अनुभव नहीं है, इसलिए मैं शायद इसके खिलाफ पक्षपाती हूं, लेकिन मुझे नहीं लगता कि बड़े अनुप्रयोगों को लिखते समय वैश्विक राज्य की कमी एक फायदा है।


0

जावास्क्रिप्ट के मामले में, जिसे आपने अपने प्रश्न में उपयोग किया था, इसके बारे में जागरूक होने के लिए एक महत्वपूर्ण बिंदु है: जावास्क्रिप्ट एकल-थ्रेडेड है, और निष्पादन का क्रम तब तक की गारंटी है जब तक कि कोई एस्किंक कॉल नहीं हैं।

तो अगर आप की तरह एक अनुक्रम है:

const nbOfUsers = getNbOfUsers();

आपको गारंटी दी जाती है कि इस बीच कुछ और निष्पादित नहीं किया जाएगा। ताले या कुछ भी समान की आवश्यकता नहीं है।

हालांकि, अगर getNbOfUsersअतुल्यकालिक है, तो:

const nbOfUsers = await getNbOfUsers();

इसका मतलब है कि getNbOfUsersरन करते समय , निष्पादन पैदावार, और अन्य कोड बीच में चल सकते हैं। यह बदले में कुछ लॉकिंग की आवश्यकता हो सकती है, जो आप कर रहे हैं पर निर्भर करता है।

इसलिए, जब कॉल असिंक्रोनस हो और जब यह किसी स्थिति में न हो, तो अतिरिक्त सावधानी बरतने के लिए आपको कॉल को सिंक्रोनाइज़ करने की आवश्यकता नहीं होगी।


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

@ यह मेरी बात नहीं है। मेरा कहना है कि एसिंक्रोनस कॉल के निष्पादन के दौरान निष्पादन प्रवाह आपके कोड के अन्य भागों में हो सकता है, जबकि यह एक तुल्यकालिक कॉल के लिए संभव नहीं है। यह कई धागों के चलने जैसा होगा लेकिन इसके बारे में पता नहीं होना चाहिए। यह बड़े मुद्दों में समाप्त हो सकता है (जो आमतौर पर पता लगाने और पुन: पेश करने के लिए कठिन होते हैं)।
जकारोन

-4

यह C ++ में std::asyncC ++ 11 से उपलब्ध है।

टेम्पलेट फ़ंक्शन async फ़ंक्शन को असिंक्रोनस रूप से चलाता है (संभवतः एक अलग थ्रेड में जो थ्रेड पूल का हिस्सा हो सकता है) और एक std :: future देता है जो अंततः उस फ़ंक्शन कॉल के परिणाम को रखेगा।

और C ++ 20 के साथ इस्तेमाल किया जा सकता है:


5
इस सवाल का जवाब नहीं लगता है। आपके लिंक के अनुसार: "कोराटाइन टीएस हमें क्या देता है? तीन नई भाषाएं कीवर्ड: co_await, co_yield और co_return" ... लेकिन सवाल यह है कि हमें पहली जगह में await(या co_awaitइस मामले में) कीवर्ड की आवश्यकता क्यों है ?
आर्टुरो टॉरेस सैंचेज़
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.