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


36

फोरट्रान और बेसिक के शुरुआती दिनों में, अनिवार्य रूप से सभी कार्यक्रम गोटो बयानों के साथ लिखे गए थे। परिणाम स्पेगेटी कोड था और समाधान संरचित प्रोग्रामिंग था।

इसी तरह, पॉइंटर्स को हमारे कार्यक्रमों में विशेषताओं को नियंत्रित करना मुश्किल हो सकता है। C ++ ने बहुत सारे पॉइंटर्स के साथ शुरुआत की, लेकिन संदर्भों के उपयोग की सिफारिश की जाती है। एसटीएल जैसे पुस्तकालय हमारी निर्भरता को कम कर सकते हैं। स्मार्ट पॉइंटर्स बनाने के लिए मुहावरे भी हैं जिनमें बेहतर विशेषताएं हैं, और सी ++ के कुछ संस्करण संदर्भ और प्रबंधित कोड हैं।

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

मेरे पढ़ने में, मैंने बहु-प्रक्रिया और मल्टी-थ्रेड प्रोग्रामिंग के उदाहरण देखे हैं जो अर्ध-उपयोग नहीं करते हैं। क्या वे अलग-अलग नामों के साथ एक ही चीज़ का उपयोग करते हैं या क्या उनके पास समवर्ती उपयोग से संसाधनों की सुरक्षा के नए तरीके हैं?

उदाहरण के लिए, मल्टीकोर प्रोसेसर के साथ मल्टीथ्रेड प्रोग्रामिंग के लिए एक सिस्टम का एक विशिष्ट उदाहरण ओपनएमपी है। यह एक महत्वपूर्ण क्षेत्र का प्रतिनिधित्व करता है, जो कि अर्धचालक के उपयोग के बिना होता है, जो पर्यावरण में शामिल नहीं हैं।

th_id = omp_get_thread_num();
#pragma omp critical
{
  cout << "Hello World from thread " << th_id << '\n';
}

इस उदाहरण से एक अंश है: http://en.wikipedia.org/wiki/OpenMP

वैकल्पिक रूप से, फ़ंक्शन प्रतीक्षा () और सिग्नल () के साथ सेमाफोर का उपयोग करके एक दूसरे से धागे की समान सुरक्षा इस तरह दिख सकती है:

wait(sem);
th_id = get_thread_num();
cout << "Hello World from thread " << th_id << '\n';
signal(sem);

इस उदाहरण में, चीजें बहुत सरल हैं, और बस एक साधारण समीक्षा प्रतीक्षा () और सिग्नल () कॉल से मेल खाने के लिए पर्याप्त है और यहां तक ​​कि बहुत अधिक संगामिति के साथ, थ्रेड सुरक्षा प्रदान की जाती है। लेकिन अन्य एल्गोरिदम अधिक जटिल हैं और कई स्थितियों के साथ कई कार्यों में फैले कई सेमाफोर (बाइनरी और काउंटिंग दोनों) का उपयोग करते हैं जिन्हें कई थ्रेड्स कहा जा सकता है। गतिरोध पैदा करने या चीजों को सुरक्षित रखने में विफल रहने के परिणामों को प्रबंधित करना कठिन हो सकता है।

क्या OpenMP जैसे ये सिस्टम सेमाफोरस के साथ समस्याओं को खत्म करते हैं?
क्या वे समस्या को कहीं और ले जाते हैं?
अब मैं एल्गोरिथ्म का उपयोग करके अपने पसंदीदा सेमाफोर को कैसे परिवर्तित करूं जो कि सेमीफोर का उपयोग न करे?


आप वास्तव में क्या बात कर रहे हैं? तुमने क्या देखा?
svick

4
अशिष्ट होने का अर्थ नहीं है, लेकिन आप पहले तीन पैराग्राफ को समाप्त कर सकते थे। वे वास्तव में आपके प्रश्न पर सहन नहीं करते हैं, और वे अपने निष्कर्ष पर पहुंच जाते हैं और बहुत तर्क उत्पन्न करेंगे।
dbracey

1
वाह, बड़ा संपादन। मैंने जवाब में एक छुरा लिया है। सवाल अभी भी गोटो, पॉइंटर्स, इनहेरिटेंस और बहुरूपता के माध्यम से घूमता है, लेकिन मेरे जवाब में मैंने इन मुद्दों को अलग रखा है और "पदावनत प्रथाओं" प्रश्न पर ध्यान केंद्रित किया है।
स्टुअर्ट मार्क्स

जवाबों:


15

क्या समवर्ती प्रोग्रामिंग तकनीक और प्रथाएं हैं जिनका अब उपयोग नहीं करना चाहिए? मैं हाँ कहूँगा ।

एक प्रारंभिक समवर्ती प्रोग्रामिंग तकनीक जो आजकल दुर्लभ प्रतीत होती है, वह बाधित-संचालित प्रोग्रामिंग है। इस तरह 1970 में UNIX ने काम किया। UNIX ऑपरेटिंग सिस्टम पर UNIX या Bach के डिज़ाइन पर लायंस कमेंटरी देखें । संक्षेप में, तकनीक एक डेटा संरचना में हेरफेर करते समय अस्थायी रूप से व्यवधान को निलंबित करने के लिए है, और फिर बाद में व्यवधान को बहाल करने के लिए है। बीएसडी spl (9) आदमी पेजकोडिंग की इस शैली का एक उदाहरण है। ध्यान दें कि व्यवधान हार्डवेयर-उन्मुख होते हैं, और कोड हार्डवेयर के व्यवधान और उस हार्डवेयर से जुड़ी डेटा संरचनाओं के बीच एक अंतर्निहित संबंध का प्रतीक है। उदाहरण के लिए, कोड जो डिस्क I / O बफ़र्स में हेरफेर करता है, उन बफ़र्स के साथ काम करते समय डिस्क नियंत्रक हार्डवेयर से व्यवधान को निलंबित करने की आवश्यकता होती है।

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

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

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

अतिरिक्त पुस्तकालय निर्माण हैं, जैसे कि जावा के java.util.concurrentपैकेज में, जिसमें विभिन्न समवर्ती डेटा संरचनाएं और थ्रेड पूलिंग निर्माण शामिल हैं। इन्हें अतिरिक्त तकनीकों के साथ जोड़ा जा सकता है जैसे कि थ्रेड कन्फाइनमेंट और प्रभावी अपरिवर्तनीयता। Goetz et द्वारा Java Concurrency प्रैक्टिस में देखें । अल। आगे की चर्चा के लिए। दुर्भाग्य से, कई प्रोग्रामर अभी भी अपने स्वयं के डेटा संरचनाओं को ताले और शर्तों के साथ रोल कर रहे हैं, जब उन्हें वास्तव में समवर्ती हाशपॉज जैसी चीज का उपयोग करना चाहिए, जहां पुस्तकालय लेखकों द्वारा पहले ही भारी लिफ्टिंग की जा चुकी है।

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

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

संपादित करें: अंत में विशिष्ट प्रश्नों के लिए मेरी प्रतिक्रिया है।

मैं OpenMP के बारे में ज्यादा नहीं जानता। मेरी धारणा है कि यह अत्यधिक समानांतर समस्याओं जैसे कि संख्यात्मक सिमुलेशन के लिए बहुत प्रभावी हो सकता है। लेकिन यह सामान्य उद्देश्य नहीं लगता है। सेमाफोर का निर्माण काफी निम्न स्तर का लगता है और प्रोग्रामर को उपर्युक्त सभी समस्याओं के साथ सेमाफोर और साझा डेटा संरचनाओं के बीच संबंध बनाए रखने की आवश्यकता होती है।

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


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

+1 java.util.concurrent के लिए और टिप्पणी पर सहमत - यह 1.5 के बाद से JDK में है और मैं शायद ही कभी इसे इस्तेमाल करते हुए देखता हूं।
MebAlone

1
मेरी इच्छा है कि जब आप पहले से ही मौजूद हों तो अपनी खुद की संरचनाओं को रोल न करना कितना महत्वपूर्ण है। इतने सारे, इतने सारे कीड़े ...
corsiKa

मुझे लगता है कि यह कहना सही नहीं है, "सेमाफोर इंटरप्ट पर एक अग्रिम हैं क्योंकि वे सॉफ्टवेयर निर्माण (हार्डवेयर से संबंधित नहीं) " हैं। Semaphores तुलना और स्वैप निर्देश को लागू करने के लिए CPU पर निर्भर करता है , या यह मल्टी-कोर वेरिएंट है
जोश पियर्स

@JoshPearce बेशक सेमाफोर्स हार्डवेयर कंस्ट्रक्शंस का उपयोग करके कार्यान्वित किया जाता है, लेकिन वे एक अमूर्त हैं जो किसी भी विशेष हार्डवेयर निर्माण से स्वतंत्र हैं, जैसे कि CAS, टेस्ट-एंड-सेट, cmpxchng, आदि
स्टुअर्ट मार्क

28

सवाल का जवाब है

सामान्य सर्वसम्मति साझा की जाने वाली स्थिति बैड ™ है, और अपरिवर्तनीय स्थिति Good ™ है, जो कार्यात्मक भाषाओं और अनिवार्य भाषाओं के साथ-साथ बार-बार सटीक और सही साबित होती है।

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

फूला हुआ प्रेम

यह प्रश्न एक दोषपूर्ण आधार की तुलना पर आधारित है; यह GOTOवास्तविक समस्या थी और कुछ हद तक इंटरलॉजिकल यूनिवर्सल बोर्ड ऑफ़ लैंग्वेज डिज़ाइनर्स और सॉफ्टवेयर इंजीनियरिंग यूनियन्स © द्वारा कैसे चित्रित किया गया था ! एक GOTOतंत्र के बिना ASM बिल्कुल काम नहीं करेगा। इस आधार के साथ कि कच्चे संकेत सी या सी ++ के साथ समस्या हैं और कुछ स्मार्ट संकेत कैसे रामबाण हैं, वे नहीं हैं।

GOTOसमस्या नहीं थी, प्रोग्रामर समस्या थे। सामायिक उत्परिवर्तित अवस्था के लिए समान है । यह स्वयं की समस्या नहीं है , यह प्रोग्रामर इसका उपयोग कर रहे हैं यही समस्या है। यदि कोड उत्पन्न करने का एक तरीका था जो साझा उत्परिवर्तित स्थिति का उपयोग करता था, जिसमें कभी भी कोई दौड़ की स्थिति या कीड़े नहीं थे, तो यह एक मुद्दा नहीं होगा। बहुत पसंद है अगर आप स्पेगेटी कोड को कभी भी नहीं GOTOबनाते हैं, तो यह एक मुद्दा भी नहीं है।

शिक्षा रामबाण है

इडियट प्रोग्रामर वे होते हैं, जो deprecatedहर लोकप्रिय भाषा में अभी भी GOTOप्रत्यक्ष या अप्रत्यक्ष रूप से निर्माण होते हैं और यह best practiceतब होता है जब हर भाषा का सही तरीके से उपयोग किया जाता है जिसमें इस प्रकार के निर्माण होते हैं।

उदाहरण: जावा में लेबल होते हैं और try/catch/finallyदोनों सीधे GOTOबयानों के रूप में काम करते हैं ।

अधिकांश जावा प्रोग्रामर, जिनसे मैं बात करना भी नहीं जानता, immutableवास्तव में उनके बाहर the String class is immutableएक ज़ोंबी के साथ दोहराए जाने का क्या मतलब है जैसे उनकी आँखों में दिखता है। वे निश्चित रूप से नहीं जानते किfinalimmutable क्लास बनाने के लिए कीवर्ड का सही उपयोग कैसे करें । इसलिए मुझे पूरा यकीन है कि उन्हें इस बात का कोई अंदाजा नहीं है कि अपरिवर्तनीय संदेशों का उपयोग करते हुए संदेश भेजना इतना शानदार क्यों है और साझा किए जाने योग्य पारस्परिक स्थिति इतनी महान क्यों नहीं है।


3
+1 महान उत्तर, स्पष्ट रूप से लिखित और परस्पर स्थिति के अंतर्निहित पैटर्न को इंगित करता है। IUBLDSEU एक मेम बन जाना चाहिए :)
डिब्बेके

2
GOTO 'कृपया, नहीं, कृपया यहां एक लौ युद्ध शुरू करें, आई डबल डॉग डेयर यू' के लिए एक कोडवर्ड है। यह सवाल आग की लपटों को शांत करता है लेकिन वास्तव में एक अच्छा जवाब नहीं देता है। कार्यात्मक प्रोग्रामिंग और अपरिवर्तनीयता के माननीय उल्लेख महान हैं, लेकिन उन बयानों के लिए कोई मांस नहीं है।
इवान प्लाइस

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

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

1
कई कार्यक्रमों को उन चीजों के मॉडल के लिए माना जाता है जो वास्तविक दुनिया में हैं, जो परस्पर हैं। अगर सुबह 5:37 बजे, वस्तु # 451 उस क्षण (5:37 पूर्वाह्न) पर वास्तविक दुनिया में किसी चीज़ की स्थिति रखती है, और वास्तविक दुनिया की स्थिति बाद में बदलती है, तो यह संभव है कि वस्तु का प्रतिनिधित्व करने वाली पहचान के लिए वास्तविक दुनिया की वस्तु अपरिवर्तनीय होने की स्थिति (अर्थात वस्तु को हमेशा वस्तु # 451 द्वारा दर्शाया जाएगा), या वस्तु # 451 के लिए अपरिवर्तनीय होना चाहिए, लेकिन दोनों नहीं। कई मामलों में, पहचान का अपरिवर्तनीय होना ऑब्जेक्ट # 451 के अपरिवर्तनीय होने की तुलना में अधिक सहायक होगा।
सुपरकैट

27

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

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

दूसरे मॉडल के बारे में मुझे पता है कि ताले और धागे का उपयोग नहीं किया जाता है जो कि वायदा का उपयोग करके होता है जो वास्तव में async प्रोग्रामिंग का सिर्फ एक और रूप है।

मुझे यकीन नहीं है कि यह तकनीक C ++ में कितनी उपलब्ध है, लेकिन संभावना है कि यदि आप कुछ ऐसा देख रहे हैं जो स्पष्ट रूप से थ्रेड्स और लॉक का उपयोग नहीं कर रहा है, तो यह संगामिति के प्रबंधन के लिए उपरोक्त तकनीकों में से एक होगा।


नए शब्द "बालों के विवरण" के लिए +1। योग्य व्यक्ति। मैं इस नए पद पर हँसना बंद नहीं कर सकता। मुझे लगता है कि मैं अब से "बालों वाला कोड" का उपयोग करने वाला हूं।
सईद नेमाटी

1
@ सईद: मैंने उस अभिव्यक्ति को पहले सुना है, यह असामान्य नहीं है। मैं सहमत हूँ कि यह मज़ेदार है लेकिन :-)
कैमरून

1
अच्छा उत्तर। .NET CLI को सिग्नलिंग के लिए भी समर्थन प्राप्त है (लॉकिंग के विपरीत), लेकिन मुझे अभी तक एक ऐसे उदाहरण के बारे में पता नहीं है जहाँ इसने लॉकिंग को पूरी तरह से बदल दिया है। मुझे यकीन नहीं है कि async मायने रखता है। यदि आप जावास्क्रिप्ट / NodeJs जैसे प्लेटफार्मों के बारे में बात कर रहे हैं, तो वे वास्तव में एकल-थ्रेडेड हैं और केवल उच्च IO लोड पर बेहतर हैं क्योंकि वे अधिकतम संसाधन सीमाएं कम करने के लिए अतिसंवेदनशील हैं (जैसे कि थ्रोवे संदर्भों की एक टन पर)। CPU सघन लोड पर Async प्रोग्रामिंग का उपयोग करने के लिए बहुत कम / कोई लाभ नहीं है।
इवान प्लाइस

1
दिलचस्प जवाब, मैं पहले वायदा करके नहीं आया था । यह भी ध्यान दें कि आप अभी भी Erlang जैसे संदेश पासिंग सिस्टम में गतिरोध और लाइवलॉक कर सकते हैं । CSP आपको औपचारिक रूप से गतिरोध और लाइवलॉक के बारे में कारण देता है लेकिन यह इसे अपने आप से रोकता नहीं है।
मार्क बूथ

1
मैं लॉक मुक्त जोड़ूंगा और उस सूची में मुफ्त डेटा संरचनाओं की प्रतीक्षा करूंगा।
स्टोनमेटल

3

मुझे लगता है कि यह ज्यादातर अमूर्त के स्तरों के बारे में है। प्रोग्रामिंग में अक्सर, यह कुछ विवरणों को इस तरह से दूर करने के लिए उपयोगी होता है जो सुरक्षित या अधिक पठनीय या ऐसा कुछ होता है।

यह संरचनाओं को नियंत्रित करने के लिए लागू होता है: ifएस, forएस और यहां तक ​​कि try- catchब्लॉक केवल gotoएस पर सार हैं । ये सार लगभग हमेशा उपयोगी होते हैं, क्योंकि वे आपके कोड को अधिक पठनीय बनाते हैं। लेकिन ऐसे मामले हैं जब आपको अभी भी उपयोग करने की आवश्यकता होगी goto(जैसे यदि आप हाथ से विधानसभा लिख ​​रहे हैं)।

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

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

आपको पता होना चाहिए कि आपके पास कौन से उपकरण उपलब्ध हैं और उनके फायदे और नुकसान क्या हैं। तब आप अपने कार्य (यदि कोई हो) के लिए सही अमूर्तता चुन सकते हैं। अमूर्त के उच्च स्तर निचले स्तर को नहीं दर्शाते हैं, हमेशा कुछ ऐसे मामले होंगे जहां अमूर्तता उपयुक्त नहीं है और सबसे अच्छा विकल्प "पुराने तरीके" का उपयोग करना है।


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

2

हां, लेकिन आप उनमें से कुछ में भाग लेने की संभावना नहीं रखते हैं।

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

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

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


धन्यवाद। ऐसा लगता है कि समवर्ती प्रोग्रामिंग के उपयोग के लिए बहुत संभावनाएं हैं, लेकिन यदि यह अनुशासित तरीके से उपयोग नहीं किया जाता है, तो यह पेंडोरा बॉक्स हो सकता है।
डेवलपरडॉन

2

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

जब मैं उन वातावरणों में कार्यक्रम करता हूँ जहाँ यह उपलब्ध है, तो इसने मेरे अधिकांश धागों, तालों और अंतर-धागा संचार को प्रतिस्थापित कर दिया था।


1

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

यह एक कारण है कि async या task-based (जैसे Grand Central Dispatch, या Intel का TBB) फ्रेमवर्क अधिक लोकप्रिय है, वे एक समय में कोड 1 कार्य चलाते हैं, इसे अगले एक पर जाने से पहले पूरा कर लेते हैं - हालाँकि, आपको प्रत्येक कोड चाहिए प्रत्येक कार्य में थोड़ा समय लगेगा जब तक आप डिज़ाइन को पेंच नहीं करना चाहते (यानी आपके समानांतर कार्य वास्तव में पंक्तिबद्ध हैं)। सीपीयू-गहन कार्यों को सभी कार्यों को संसाधित करने वाले एकल थ्रेड प्रसंस्करण पर संसाधित करने के बजाय एक वैकल्पिक सीपीयू कोर को पारित किया जाता है। इसका प्रबंधन करना भी आसान है अगर वास्तव में बहु-थ्रेडेड प्रसंस्करण नहीं हो रहा है।


कूल, Apple और Intel तकनीक के संदर्भ के लिए धन्यवाद। क्या आपका जवाब धागे को कोर आत्मीयता के प्रबंधन की चुनौतियों की ओर इशारा करता है? कुछ कैश प्रदर्शन समस्याओं को कम किया जाता है क्योंकि मल्टीकोर प्रोसेसर एल 1 कैश प्रति कोर दोहरा सकते हैं? उदाहरण के लिए: software.intel.com/en-us/articles/… अधिक कोर हिट वाली चार कोर के लिए हाई स्पीड कैश 4x से अधिक हो सकता है, जितना कि एक ही डेटा पर एक से अधिक कैश मिस के साथ एक कोर। मैट्रिक्स गुणन कर सकते हैं। 4 कोर पर 32 धागे का रैंडम शेड्यूलिंग नहीं कर सकता। चलो आत्मीयता का उपयोग करें और 32 कोर प्राप्त करें।
DeveloperDon

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