दिलचस्प पोस्ट
एक git submodule के लिए दूरस्थ रिपॉजिटरी बदलना नुम्पी: मूल्य का पहला सूचकांक तेजी से ढूंढें वैरिएबल का समाधान नहीं किया जा सकता एक्स्टेंट्स के साथ कई अक्षर बदलें gsub के साथ ASP.NET MVC यूआरएल रूट का समर्थन (डॉट) एनएलटीके में पार्सिंग के लिए अंग्रेजी व्याकरण जब उपयोगकर्ता स्क्रीन को पिन कर देता है तो एक UIImage ऑब्जेक्ट ज़ूम इन / आउट कैसे करें? एनटीआई फ़्रेमवर्क फ़्लुएंट सिंटैक्स या इनलाइन वाक्यविन्यास का उपयोग करके पुनरावर्ती सीटीटी लेखन स्रोत नियंत्रण में हडसन / जेनकींस कॉन्फ़िगरेशन फ़ाइलों को रखने का कोई तरीका है? नॉकआउट में अद्यतन नहीं करने योग्य अवलोकन के मूल्य निर्धारित करना क्लास जावा लॉकहेल्पर दो स्थानों पर लागू किया गया है सिस्टम ट्रे को ऐप को छोटा करें जावा में एक सूचक और एक संदर्भ चर के बीच अंतर क्या है? आईआईएस 7 एपलीकेशन पूल में नेट फ्रेमवर्क 4.5 संस्करण कैसे सेट करें I कैसे कॉम से अलग किए गए मानों के साथ टेक्स्ट फ़ाइल में / पढ़ने के लिए

क्या यह एक धागे के भीतर से कांटा सुरक्षित है?

मुझे समझाने दो: मैं पहले से ही लिनक्स पर एक आवेदन विकसित कर रहा हूं जो बाहरी बाइनरी कांटा और निष्पादित करता है और इसे समाप्त करने के लिए इंतजार करता है। परिणामों को shm फ़ाइलें जो कि fork + प्रक्रिया के लिए अद्वितीय हैं द्वारा भेजी जाती हैं पूरे कोड को एक वर्ग के भीतर समझाया जाता है।

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

क्या यह धागा सुरक्षित है? यदि मैं एक धागे के भीतर कांटा, सुरक्षित होने के अलावा, मुझे कुछ देखना है? कोई सलाह या मदद की बहुत सराहना की है!

वेब के समाधान से एकत्रित समाधान "क्या यह एक धागे के भीतर से कांटा सुरक्षित है?"

fork आईएनजी, धागे के साथ भी, सुरक्षित है एक बार जब आप कांटा देते हैं, तो धागे प्रति प्रक्रिया स्वतंत्र होते हैं (यह है, थ्रेडिंग ऑर्थोगोनल फोर्किंग के लिए है)। हालांकि, यदि विभिन्न प्रक्रियाओं में थ्रेड्स समान साझा स्मृति का उपयोग करने के लिए comunicate, आप को एक तुल्यकालन तंत्र विकसित करना होगा

समस्या यह है कि कांटा () केवल कॉलिंग धागे की प्रतिलिपि बनाते हैं, और बच्चे के थ्रेड्स में रखे गए किसी भी म्यूट को हमेशा फोके हुए बच्चे में बंद कर दिया जाएगा। Pthread समाधान pthread_atfork() हैंडलर था यह विचार था कि आप 3 संचालकों को पंजीकृत कर सकते हैं: एक प्रीफर्क, एक माता पिता हैंडलर, और एक बच्चे के हैंडलर जब fork() होता है prefork को कांटा से पहले कहा जाता है और सभी अनुप्रयोग म्यूटक्स प्राप्त करने की उम्मीद है। माता-पिता और बच्चे दोनों को क्रमशः अभिभावक और बाल प्रक्रियाओं में सभी म्यूटक्स जारी करना चाहिए।

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

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

उदाहरण के लिए, इस अनुक्रम पर विचार करें:

  1. धागा T1 कॉल fork()
  2. टी 1 में प्राप्त लाइब्रेरी के लिए प्रीफर्क हैंडलर
  3. इसके बाद, थ्रेड टी 2 में, एक तृतीय पक्ष लाइब्रेरी ए ने अपना म्यूटिक्स एएम हासिल किया है, और फिर एक लाइब्रेरी कॉल करता है जिसमें म्यूट एक्स की आवश्यकता होती है। यह ब्लॉक, क्योंकि libc mutexes T1 द्वारा आयोजित किए जाते हैं
  4. थ्रेड T1 लाइब्रेरी ए के लिए प्रीफर्क हैंडलर चलाता है, जो कि एएम को प्राप्त करने के लिए रोकता है, जिसे टी 2 द्वारा आयोजित किया जाता है।

आपका डेडलॉक है और यह आपके अपने म्यूटक्स या कोड से असंबंधित है।

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

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

जब आप अपने प्रोग्राम के लिए लिनक्स के एनपीटीएल pthreads(7) समर्थन का उपयोग कर सकते हैं, तो धागे यूनिक्स सिस्टम पर एक अजीब फिट हैं, जैसा कि आपने अपने fork(2) प्रश्नों के साथ खोज की है

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

लेकिन यदि आप थ्रेडिंग का उपयोग करना चुनते हैं, तो आप fork(2) मैनपेज से निम्नलिखित संकेतों के साथ एक नई प्रक्रिया का उपयोग कर सकते हैं :

  * The child process is created with a single thread — the one that called fork(). The entire virtual address space of the parent is replicated in the child, including the states of mutexes, condition variables, and other pthreads objects; the use of pthread_atfork(3) may be helpful for dealing with problems that this can cause. 

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

यहाँ भेद "हेवीवेट प्रक्रियाओं" के साथ है, जो पूर्ण पता स्थान हैं I एक नई हेवीवेट प्रक्रिया कांटा द्वारा बनाई गई है (2) । जैसा कि आभासी स्मृति UNIX दुनिया में आया, जो vfork (2) और कुछ अन्य के साथ संवर्धित किया गया था

एक कांटा (2) सभी रजिस्टरों सहित प्रक्रिया का पूरा पता स्थान प्रतिलिपि बनाता है, और उस प्रक्रिया को ऑपरेटिंग सिस्टम शेड्यूलर के नियंत्रण में रखता है; अगली बार शेड्यूलर के आसपास आता है, निर्देश काउंटर अगले निर्देश पर उठाता है – फोर्केड बाल प्रक्रिया माता-पिता के एक क्लोन है। (यदि आप किसी अन्य प्रोग्राम को चलाने के लिए चाहते हैं, तो कहें कि आप एक शेल लिख रहे हैं, तो आप एक कमान (2) कॉल के साथ कांटा का पालन करते हैं, जो नए प्रोग्राम के साथ नया पता स्थान लोड करता है, जिसे क्लोन किया गया था।

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

यह चाल यहां तक ​​कि उपयोगी है: कई कार्यक्रमों में, आपके पास एक मूल प्रक्रिया होती है जिसमें कई थ्रेड हो सकते हैं, जिनमें से कुछ नए बाल प्रक्रियाओं का उपयोग करते हैं (उदाहरण के लिए, एक HTTP सर्वर ऐसा कर सकता है: पोर्ट 80 से प्रत्येक कनेक्शन को एक थ्रेड द्वारा नियंत्रित किया जाता है, और फिर सीजीआई कार्यक्रम जैसे कुछ के लिए एक बाल प्रक्रिया काटा जा सकता है; exec (2) तब सीजीआई प्रोग्राम चलाने के लिए कहा जाएगा मूल प्रक्रिया बंद होने के स्थान पर।)

यदि आप यूनिक्स 'कांटा ()' सिस्टम कॉल का उपयोग कर रहे हैं, तो आप तकनीकी रूप से धागे का उपयोग नहीं कर रहे हैं- आप प्रक्रियाओं का उपयोग कर रहे हैं- उनकी अपनी स्मृति स्थान होगी, और इसलिए प्रत्येक के साथ हस्तक्षेप नहीं कर सकते।

जब तक प्रत्येक प्रक्रिया अलग-अलग फाइलों का उपयोग करती है, तब तक कोई समस्या नहीं होनी चाहिए।

आप जल्दी से या तो फोर्क बाल प्रक्रिया में exec या _exit कॉल करते हैं, तो आप अभ्यास में ठीक हैं

आप शायद posix_spawn () का उपयोग करना चाहते हैं, जो संभवत: सही बात करेंगे।