2012-10-13 11 views
6

संभव डुप्लिकेट:
fork in multi-threaded programधागे और कांटा()। मैं उससे कैसे निपट सकता हूं?

यदि मैं किसी एप्लिकेशन जो कांटा() काम करते हैं और बहु ​​के रूप में विकसित किया जा सकता है, क्या अंगूठे नियम हैं है/दिशा-निर्देश सुरक्षित रूप से इस कार्यक्रम पर विचार करने के आवेदन की तरह?

+0

@JensGustedt मैं मूल रूप से हालांकि तो भी, लेकिन इस धागे और _fork() _ लिनक्स पर के बारे में एक व्यापक सवाल की तर्ज पर अधिक होना चाहिए: और का एक बहुत के लिए तैयार रहना। – Emanuele

उत्तर

4

बुनियादी अंगूठे के नियम, जैसे (http://www.linuxprogrammingblog.com/threads-and-fork-think-twice-before-using-them, fork in multi-threaded program) विभिन्न इंटरनेट लेख के अनुसार कर रहे हैं:

  1. (मुख्य) प्रक्रिया [0] Monothread -> कांटा() -> (बच्चा) प्रक्रिया [1] मल्टीथ्रेडेड: ठीक है!
    प्रक्रिया [1] दुर्घटनाओं या स्मृति के साथ चारों ओर भोजनालयों यह होगा प्रक्रिया की नहीं स्पर्श पता स्थान [0] (जब तक आप आर/डब्ल्यू स्मृति साझा का उपयोग करें ... लेकिन इस का एक और विषय है अपना ही है)।
    डिफ़ॉल्ट रूप से लिनक्स में सभी कांटा() ed मेमोरी Copy On Write है। , यह देखते हुए कि [0] प्रक्रिया monothreaded है जब हम कांटा आह्वान() सभी संभव पारस्परिक अपवर्जन पुरातन आम तौर पर एक खुला राज्य में होना चाहिए।

  2. (मुख्य) प्रक्रिया [0] थ्रेड -> कांटा() -> (बच्चा) प्रक्रिया [1] मोनो/Multithread: खराब!
    आप कांटा() एक थ्रेड प्रक्रिया अपने mutexes और कई अन्य धागा तुल्यकालन पुरातन संभावना प्रक्रिया में एक अपरिभाषित राज्य में हो जाएगा [1]। आप pthread_atfork() के साथ काम कर सकते हैं लेकिन यदि आप पुस्तकालयों का उपयोग करते हैं तो आप एक पासा रोल कर सकते हैं और भाग्यशाली होने की उम्मीद कर सकते हैं। क्योंकि आम तौर पर आप पुस्तकालयों के कार्यान्वयन विवरण को नहीं जानते (चाहते हैं)।

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

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

तो बेहतर होगा आप अपने मुख्य प्रक्रिया थ्रेड है, कांटा() का उपयोग करने से राग।यह एक स्थिर तरीके से इसे लागू करने के लिए उचित गड़बड़ होने जा रहा है।

चीयर्स

-1

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

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

तो हालांकि यह काम कर सकता है, मैं बस परीक्षण का सुझाव देता हूं, और पहले एक और तरीका खोजने की कोशिश करता हूं।

Segmentation fault 
+1

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

+0

@Linuxios इस अतिरिक्त स्पष्टीकरण के लिए धन्यवाद कि लिनक्स के तहत धागे कैसे बनाए जाते हैं, लेकिन _clone() _ कॉल नहीं होना चाहिए जो तकनीकी रूप से उपयोग किया जाता है? मुझे लगता है कि यह समग्र शर्तों में थोड़ा उलझन में है। चीयर्स – Emanuele

+0

@Emanuele: यही वही है जो मैं मानता हूं। क्लोन कॉल – Linuxios

संबंधित मुद्दे