2010-04-29 8 views
7

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

तो क्या एक सी प्रोग्राम से एक शेल स्क्रिप्ट का आह्वान करने का कोई तरीका है बिना फोर्क() के मेमोरी ओवरहेड किए बिना?

मैंने कामकाज पर विचार किया है जैसे कि द्वितीयक छोटी प्रक्रिया है जो गोले बनाने के लिए ज़िम्मेदार है, या एक "वॉचर" स्क्रिप्ट है जिसे मैं किसी फ़ाइल या किसी चीज़ को छूकर सिग्नल करता हूं, लेकिन मुझे कुछ आसान होना चाहिए।

+0

देखें ग्रेग Hewgill का जवाब।यह मंच पर कुछ हद तक निर्भर है - क्या आप कृपया इस बात का विस्तार कर सकते हैं कि आप किस प्लेटफॉर्म का उपयोग कर रहे हैं (उदा। क्या इसमें एमएमयू है?) – ConcernedOfTunbridgeWells

+0

क्या यह एक प्रश्न का डुप्ली नहीं है * कल * ?? http://stackoverflow.com/questions/2731531/faster-forking-of-large-processes-on-linux –

+0

हां और नहीं, @ पावेल, यह लिनक्स-विशिष्ट नहीं है और इसमें अतिरिक्त जानकारी है जो निष्पादित किया जा रहा है - एक खोल स्क्रिप्ट। अन्य प्रश्नकर्ता के पास थ्रेड का उपयोग करने के लिए अपने आवेदन को फिर से लिखने का विकल्प हो सकता है (यदि निष्पादित प्रोग्राम बैश/केश/अन्य-खोल के बजाए उनके नियंत्रण में निष्पादन योग्य था) लेकिन शायद इस मामले में नहीं। – paxdiablo

उत्तर

8

कुछ यूनिक्स कार्यान्वयन आपको vfork (सिंगल यूनिक्स स्पेक का हिस्सा) देगा जो कि fork जैसा है, सिवाय इसके कि यह सभी चीजों को माता-पिता के साथ साझा करता है।

vfork साथ

, वहाँ exec बुला किसी अन्य प्रक्रिया के साथ पता स्थान अधिलेखित करने से पहले चीजें आप बच्चे में क्या कर सकते हैं की एक बहुत ही सीमित संख्या में हैं - कि मूल रूप से fork/exec के लिए fork का एक न्यूनतम प्रति संस्करण क्या vfork के लिए बनाया गया था, अनुक्रम।

+0

धन्यवाद, यह वही है जो मुझे चाहिए था। – kdt

6

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

यदि आपको पता है कि आपके पास एमएमयू नहीं है, तो शायद fork() वास्तव में एक वास्तविक प्रति का उपयोग करके लागू किया गया है। एक अन्य दृष्टिकोण एक सहायक प्रक्रिया हो सकती है जो कि उपज के लिए ज़िम्मेदार है, जिसे आप पाइप का उपयोग करने के साथ संवाद करते हैं।

+0

मैंने इसे सामान्य लिनक्स 2.6 सिस्टम पर परीक्षण किया है जो कोई स्वैप विभाजन के साथ कॉन्फ़िगर नहीं किया गया है। जब मेरी मूल प्रक्रिया लगभग 300 मेग्स होती है, तो मुझे लगता है कि फोर्क() का उपयोग करने के लिए मुझे शीर्ष पर रिपोर्ट की गई कम से कम 200 एमबी मुक्त मेमोरी चाहिए। कोई भी कम और यह एक त्रुटि देता है। मुझे लगता है कि गाय केवल तभी होता है जब आपके पास एक स्वैप विभाजन हो जो लिनक्स को विश्वास दिलाता है कि यद्यपि इसे लिखने तक पृष्ठों की प्रतिलिपि बनाने की आवश्यकता नहीं है, लेकिन अगर आप ऐसा कर सकते हैं। – kdt

+3

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

-1

ऐसा लगता है जैसे इस मामले में समझदार कदम आपकी शेल स्क्रिप्ट (यदि संभव हो) को सी को बंद करना है, और प्रक्रिया के भीतर इसे निष्पादित करना है; तो आपको बिल्कुल कांटा नहीं है।

फिर फिर से; मुझे नहीं पता कि आप वास्तव में पर क्या कर रहे हैं।

-3

अपनी प्रक्रिया को खोलने के बजाय एक खोल खोलने के बजाय, अपनी प्रक्रिया (अग्रभूमि में) के भीतर एक खोल लॉन्च करें और फिर इसे खोल के भीतर फोर्क करें।

system("/bin/ash /scripts/bgtask"); 
साथ/scripts/bgtask किया जा रहा है

:

/bin/ash /scripts/propertask & 

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

+1

मुझे लगता है कि आप पाते हैं कि सिस्टम को कांटा/निष्पादन/प्रतीक्षा के रूप में लागू किया गया है, जो आपको हल करने के लिए पूछे जाने वाले प्रश्न के समान समस्या देगा। – paxdiablo

+0

paxdiablo सही है, सिस्टम() आंतरिक रूप से फोर्क() का उपयोग करता है। मैन पेज इवेंट का उल्लेख यह है कि: "... उदाहरण के लिए फोर्क() विफल ...": http://linux.die.net/man/3/system – kdt

0

मैं देख रहा हूँ आप पहले से ही एक जवाब स्वीकार कर लिया है, लेकिन आप अगर यह अपने लक्ष्य पर जो उपलब्ध है posix_spawn के बारे में पढ़ा है, तो इसका उपयोग करना चाहते हो सकता है: नीचे

http://www.opengroup.org/onlinepubs/9699919799/functions/posix_spawn.html

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

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