2011-12-16 10 views
6

मैं libfuse और glib event इंटरफ़ेस दोनों के साथ काम कर रहा हूं और मैंने एक ऐसे मुद्दे में भाग लिया है जहां मुझे कई मुख्य लूपों को एक साथ चलाने की आवश्यकता है (glib's g_main_loop_run और fuse_loop_mt)।एकाधिक मुख्य लूप चलाने के लिए संभव है?

मैं पहले से ही एक उच्च माध्यमिक संदर्भ के तहत चिकना के घटना पाश के लिए बनाई गई एक अलग धागा करने का प्रयास किया, उदा .:

static void * 
event_loop(void *arg) 
{ 
    GMainLoop *event_loop; 
    GMainContext *context;  

    context = g_main_context_new(); 
    g_main_context_push_thread_default(context); 
    event_loop = g_main_loop_new(context, FALSE); 
    g_main_loop_run(event_loop); 

    return NULL; 
} 

... 

pthread_t event_thread; 
pthread_attr_t thread_attr; 
pthread_attr_init(&thread_attr); 
pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); 
event_thread = pthread_create(&event_thread, &thread_attr, 
    event_loop, NULL); 

हालांकि फिसलनदार घटना पाश निकाल दिया घटनाओं में से किसी पर लेने नहीं करता है। क्या मैं यहां पूरी तरह से आधार पर हूं? एकाधिक मुख्य लूप से निपटने का सही तरीका क्या है?

+0

सबसे अच्छा तरीका मुझे लगता है कि यदि संभव हो तो एकाधिक मुख्य लूपों से बचने के लिए सबसे अच्छा तरीका होगा। वैकल्पिक रूप से ईवेंट लूप को एकीकृत करें ताकि आप ईवेंट प्राप्त करने और संसाधित करने के लिए केवल एक का उपयोग कर सकें। –

+0

दुर्भाग्यवश, यह संभव नहीं है। कर्ल हाइपर इंटरफ़ेस का उपयोग करने के लिए मुझे ग्लिब (libevent, आदि ..) इंटरफेस की आवश्यकता है। फ्यूज, स्पष्ट कारणों से भी मुख्य लूप की आवश्यकता है। –

उत्तर

4

जीएलआईबी मुख्य पाश custom event sources का समर्थन करता है। मुझे FUSE के बारे में बहुत कुछ पता नहीं है, लेकिन आप किसी अन्य धागे के भीतर FUSE के मुख्य पाश को चलाने में सक्षम हो सकते हैं, और इसकी घटनाओं को जीएलआईबी लूप में एकीकृत कर सकते हैं।

एक त्वरित खोज से पता चलता है कि आप your own main loop लिखने के लिए निम्न-स्तरीय FUSE API का उपयोग करने में सक्षम हो सकते हैं, जिसे संभावित रूप से "लूप" भाग को छोड़कर जीएलआईबी में अधिक आसानी से एकीकृत किया जा सकता है।

सामान्य रूप से, हालांकि, कई मुख्य लूप केवल बुरी खबर हैं; यही कारण है कि उन्हें मुख्य लूप कहा जाता है। :) उन्हें संभालने का सबसे अच्छा तरीका है कि आप जो भी लूप आपके लिए सबसे अच्छा काम करते हैं, सीधे ईवेंट को हुक करके उन्हें खत्म करना है। दुर्भाग्यवश, सभी एपीआई इसे संभव बनाने के लिए पर्याप्त हुक प्रदान नहीं करते हैं।

+0

+1 यह संभवतः यह करने का सबसे अच्छा समझदार तरीका है, लेकिन मैं कुछ जोड़ना चाहता हूं कि यदि आप लिनक्स 'eventfd' या' पाइप 'का उपयोग कर रहे हैं तो शायद ग्लिब मुख्य लूप को संदेश भेजने के अच्छे तरीके होंगे, क्योंकि वे वापसी फ़ाइल डिस्क्रिप्टर जिन्हें लगभग सीधे ग्लिब के साथ उपयोग किया जा सकता है। – Lalaland

+0

अच्छा बिंदु; यह 'फोर्क() 'के लिए भी बेहतर हो सकता है और बहु-थ्रेडिंग के साथ किसी भी समस्या के बारे में चिंता किए बिना, वहां से FUSE (या GLib) मुख्य लूप चला सकता है। – ehird

+0

धन्यवाद, एथन। मुझे डर था कि मुझे निम्न स्तर के इंटरफेस में जाना पड़ सकता है। ऐसा लगता है कि यह एक लंबा दिन होगा :) –

3

एक अलग थ्रेड या प्रक्रिया में मुख्य लूप स्थापित करने के अलावा (मेरे पास थोड़ा सा अनुभव है, अलग प्रक्रिया ने मेरे लिए बेहतर काम किया है लेकिन फिर फिर से आपके मामले में धागा अच्छी तरह से काम कर सकता है), आप विचार कर सकते हैं जीएलआईबी के मुख्य पाश में फ्यूज मुख्य लूप को एकीकृत करना (दुर्भाग्य से मुझे इसका कोई पूर्व अनुभव नहीं है)। आप इसके बारे में this thread discussion देख सकते हैं (यदि आपने इसे पहले से नहीं देखा है)। जैसा कि " Register the fuse device file descriptor (fuse_chan_fd()) with the glib event loop. Then call fuse_chan_recv() and fuse_session_process() when the event trigger" धागे के अंत में सुझाव दिया गया है। एफडी को ट्रैक करने के लिए आपको GIO (More info on Nokia developer page) का उपयोग करने की आवश्यकता होगी।
उम्मीद है कि यह कुछ संकेत प्रदान कर सकता है!

+0

धन्यवाद, यह भी सहायक है। –

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