2009-10-13 20 views
7

मैं, जागरूक प्रत्येक प्रक्रिया यह खुद स्मृति पता स्थान है, फिर भी मैं सोच रहा था बनाता है कि कर रहा हूँक्या प्रक्रियाओं में फ़ंक्शन पॉइंटर्स का उपयोग करना संभव है?

प्रक्रिया एक तरह एक समारोह के लिए किया गया था:

int DoStuff() { return 1; } 

और एक सूचक typedef की तरह:

typedef int(DoStuff_f*)(); 

और एक गेटर समारोह की तरह:

DoStuff_f * getDoStuff() { return DoStuff; } 

और के माध्यम से ... प्रक्रिया बी के साथ संवाद करने के लिए एक जादुई तरीका कहना बढ़ावा :: इंटरप्रोसेस

यह समारोह सूचक बी की प्रक्रिया और प्रक्रिया बी सीधे से

प्रक्रिया एक के DoStuff कॉल करने के लिए पारित करने के लिए संभव हो सकता है?

+2

कृपया उस ओ/एस को बताएं जिसके साथ आप काम कर रहे हैं। प्रश्न का उत्तर vxWorks बनाम लिनक्स के लिए बहुत अलग है। – kmarsh

+2

सहमत - सभी "नहीं" उत्तरों को "पोर्टेबल नहीं", और/या "मेरे ओएस पर नहीं" के रूप में समझा जाना चाहिए। बहुत हल्के ओएस वाले कुछ प्लेटफॉर्म पर कोई संरक्षित स्मृति नहीं है, और यह केवल काम करेगा। –

+0

मुझे लगता है कि यह विंडोज है। मेरी धारणा प्रारंभिक मासीक के प्रश्नों और फ़ंक्शन नामकरण की शैली के आधार पर मेरी धारणा :) –

उत्तर

8

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

उदाहरण के लिए की ओर से, कहेंगे अगर आप

////PROCESS A//// 
int processA_myfun() { return 3; } 
// get a pointer to pA_mf and pass it to process B 

////PROCESS B//// 
int processB_myfun() { return 4; } // This happens to be at the same virtual address as pA_myfun 
// get address from process A 
int x = call_myfun(); // call via the pointer 
x == 4; // x is 4, because we called process B's version! 
था

यदि प्रक्रिया ए और बी एक ही कोड चला रहे हैं, तो आप समान पते पर समान कार्यों के साथ समाप्त हो सकते हैं - लेकिन आप अभी भी बी के डेटा संरचनाओं और वैश्विक स्मृति के साथ काम करेंगे! तो संक्षिप्त जवाब है, नहीं, यह नहीं है कि आप यह कैसे करना चाहते हैं!

इसके अलावा, address space layout randomization जैसे सुरक्षा उपाय इस तरह के "चाल" को कभी भी काम करने से रोक सकते हैं।

आप आईपीसी और आरपीसी को भ्रमित कर रहे हैं। आईपीसी डेटा को संचारित करने के लिए है, जैसे आपकी ऑब्जेक्ट्स या टेक्स्ट का ब्लॉब। RPC एक दूरस्थ प्रक्रिया में कोड निष्पादित करने के लिए है।

+0

एएसएलआर के लिए +1 - मैं इसके बारे में विवरण याद रखने की कोशिश कर रहा था। –

0

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

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

+0

चला रहा हूं, इसलिए दूसरे शब्दों में: भले ही मैं बूस्ट :: इंटरपोकॉस, प्रबंधित साझा मेमोरी सेगमेंट (उदाहरण के लिए) का उपयोग करता हूं, फिर भी अगर मैं पॉइंटर पास करता हूं - यह अभी भी काम नहीं करेगा, सही? – Maciek

+1

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

+0

कृपया "प्रक्रिया" बनाम "एप्लिकेशन" की अपनी परिभाषा साझा करें। – kmarsh

8

संक्षेप में, आप फ़ंक्शन पॉइंटर का उपयोग नहीं कर सकते जो किसी अन्य प्रक्रिया में पारित हो।

फ़ंक्शन के कोड स्मृति के संरक्षित पृष्ठों में स्थित हैं, आप उन्हें नहीं लिख सकते हैं। और प्रत्येक प्रक्रिया में वर्चुअल एड्रेस स्पेस अलग है, इसलिए फ़ंक्शन का पता किसी अन्य प्रक्रिया में मान्य नहीं है। विंडोज़ में आप किसी अन्य प्रक्रिया में अपने कोड को इंजेक्ट करने के लिए this आलेख में वर्णित तकनीक का उपयोग कर सकते हैं, लेकिन विंडोज़ का नवीनतम संस्करण इसे अस्वीकार करता है।

फ़ंक्शन पॉइंटर पास करने के बजाय, आपको एक लाइब्रेरी बनाने पर विचार करना चाहिए जो दोनों प्रक्रियाओं में उपयोग किया जाएगा। इस मामले में जब आप उस फ़ंक्शन को कॉल करने की आवश्यकता होती है तो आप किसी अन्य प्रक्रिया को संदेश भेज सकते हैं।

1

यदि आपने प्रक्रिया बी से प्रक्रिया ए के फ़ंक्शन पॉइंटर का उपयोग करने का प्रयास किया है, तो आप प्रक्रिया ए को कॉल नहीं करेंगे - आप प्रक्रिया बी में जो भी हो, उसे कॉल करेंगे। यदि वे एक ही प्रोग्राम हैं तो आप भाग्यशाली हो सकते हैं और यह वही कोड होगा, लेकिन इसमें प्रक्रिया ए

1

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

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

ऐसा लगता है कि आप वास्तव में कुछ प्रकार के संदेश-पासिंग या आरपीसी सिस्टम की तरह लगता है।

+0

हाँ संदेश पास हो रहा है। बूस्ट :: इंटरप्रोसेस का उपयोग कर पहले ही लागू किया गया था, "अन्य तरीकों" के बारे में सोच रहा था – Maciek

1

यही कारण है कि लोगों ने COM, RPC और CORBA जैसी चीजों का आविष्कार किया है। उनमें से प्रत्येक इस सामान्य प्रकार की क्षमता देता है। जैसा कि आप अनुमान लगाते हैं, प्रत्येक नौकरी दूसरों से थोड़ा अलग करता है।

बूस्ट आईपीसी वास्तव में दूरस्थ प्रक्रिया कॉल का समर्थन नहीं करता है। यह साझा स्मृति में परिवर्तनीय डालने में सक्षम होगा, इसलिए यह दो प्रक्रियाओं तक पहुंच योग्य है, लेकिन यदि आप उस चर को एक्सेस करने के लिए गेटर/सेटर का उपयोग करना चाहते हैं, तो आपको इसे स्वयं करना होगा।

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

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