मेरे आवेदन में, मेरे पास एक प्रक्रिया है जो बच्चे को फोर्क करती है, बच्चे 1 कहें, और यह बाल प्रक्रिया डिस्क पर एक बड़ी बाइनरी फ़ाइल लिखती है और बाहर निकलती है। मूल प्रक्रिया तब एक और चाइल्ड प्रोसेस, चाइल्ड 2 को बंद कर देती है, जो आगे की प्रक्रिया करने के लिए इस विशाल फ़ाइल में पढ़ती है।
फ़ाइल डंपिंग और री-लोडिंग मेरे एप्लिकेशन को धीमा कर रही है और मैं डिस्क I/O से पूरी तरह से बचने के संभावित तरीकों के बारे में सोच रहा हूं। जिन संभावित तरीकों की मैंने पहचान की है वे हैं रैम-डिस्क या tmpfs। क्या मैं किसी तरह अपने आवेदन के भीतर से रैम-डिस्क या tmpfs लागू कर सकता हूं? या कोई अन्य तरीका है जिससे मैं डिस्क I/O से पूरी तरह से बच सकता हूं और प्रक्रियाओं में डेटा को विश्वसनीय रूप से भेज सकता हूं।
7 जवाब
यदि दो उप-प्रक्रियाएं एक ही समय में नहीं चलती हैं तो पाइप या सॉकेट आपके लिए काम नहीं करेंगे - उनके बफ़र्स 'विशाल बाइनरी फ़ाइल' के लिए बहुत छोटे होंगे और पहली प्रक्रिया डेटा को पढ़ने के लिए किसी भी चीज़ की प्रतीक्षा को रोक देगी।
ऐसे मामले में आपको किसी प्रकार की साझा स्मृति की आवश्यकता होती है। आप SysV IPC साझा मेमोरी API, POSIX साझा मेमोरी API (जो आंतरिक रूप से हाल के Linux पर tmpfs का उपयोग करता है) का उपयोग कर सकते हैं या सीधे tmpfs पर फ़ाइलों का उपयोग कर सकते हैं (आमतौर पर /dev/shm, कभी-कभी /tmp पर) फ़ाइल सिस्टम पर सीधे।
फोर्किंग से पहले एक अनाम साझा मेमोरी क्षेत्र बनाएं और फिर सभी बच्चे कांटे के बाद इसका उपयोग कर सकते हैं:
char *shared = mmap(0,size,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
ध्यान रखें कि स्मृति साझा करते समय आपको कुछ सिंक्रनाइज़ेशन तंत्र की आवश्यकता होगी। इसे पूरा करने का एक तरीका साझा मेमोरी क्षेत्र के अंदर एक म्यूटेक्स या सेमाफोर डालना है।
एक नामित पाइप ठीक वही है जो आप चाहते हैं। आप इसमें डेटा लिख सकते हैं और इससे डेटा पढ़ सकते हैं जैसे कि यह एक फ़ाइल थी, लेकिन इसे डिस्क पर संग्रहीत करने की कोई आवश्यकता नहीं है।
आप पाइप, सॉकेट का उपयोग कर सकते हैं और लिनक्स कर्नेल की sendfile()
या splice()
सुविधाओं का लाभ उठा सकते हैं (वे डेटा कॉपी करने से बच सकते हैं)।
दो प्रक्रियाओं को स्पॉन करें और उन्हें सॉकेट के माध्यम से डेटा स्थानांतरित करें। टीसीपी शुरू करना सबसे आसान होगा, लेकिन अगर आप थोड़ी अधिक दक्षता चाहते हैं, तो यूनिक्स डोमेन सॉकेट का उपयोग करें। यह मानता है कि आपको डिस्क पर लिखे जा रहे डेटा की परवाह नहीं है।
आप पाइप का उपयोग करके प्रक्रियाओं के बीच डेटा पास कर सकते हैं। यहां एक अच्छा सारांश और उदाहरण कार्यान्वयन है।
जैसा कि आपके मामले में पहली चाइल्ड प्रोसेस चाइल्ड 1 चाइल्ड 2 के अस्तित्व में आने से पहले बाहर निकल रही है, इसलिए सॉकेट कम्युनिकेशन या बिना नाम वाले पाइप का उपयोग करने से मदद नहीं मिलेगी,
लेकिन साझा मेमोरी काम करेगी: चाइल्ड 1 में सभी के लिए पढ़ने की अनुमति के साथ एक साझा मेमोरी सेगमेंट बनाएं और उस साझा मेमोरी में फ़ाइल डंपिंग कार्य करें, चाइल्ड 2 में साझा मेमोरी सेगमेंट को वर्तमान प्रक्रिया स्थान में संलग्न करें और डंप किए गए डेटा को पढ़ें।