मैं यह समझने की कोशिश कर रहा हूं कि जब मैं g_io_channel के साथ FIFO का उपयोग करता हूं तो मेरा CPU 100% क्यों आ जाता है।

मेरे पास github पर एक प्रोजेक्ट है जो सबसे छोटे संभव सेटअप के साथ समस्या को प्रदर्शित करता है; बस एक साधारण सर्वर जो /tmp में एक FIFO खोलता है, और एक क्लाइंट जो उस FIFO के माध्यम से सर्वर को एक संदेश भेजता है।

मुझे मिला:

  1. पहली बार शुरू होने पर, सर्वर शून्य CPU के करीब ले जाता है
  2. जैसे ही क्लाइंट FIFO के माध्यम से सर्वर को संदेश भेजता है, संदेश प्राप्त होता है और सर्वर द्वारा मुद्रित किया जाता है, और फिर CPU 100% हो जाता है।
  3. आप फीफो के माध्यम से संदेश भेजना जारी रख सकते हैं और सर्वर उन्हें प्रिंट करेगा, लेकिन वह सीपीयू 100% पर रहता है: - /

मैंने सामान्य Google, और स्टैक ओवरफ़्लो की कोशिश की है, लेकिन अभी तक समाधान खोजने पर कोई खुशी नहीं हुई है। मुझे आशा है कि कोई मुझे यह समझने में मदद कर सकता है कि क्या हो रहा है। मेरा मानना ​​है कि मैं सही ढंग से ग्लिब/जीटीके का उपयोग कर रहा हूं, लेकिन मुझे सही होने पर काफी खुशी हो रही है। मैं आपके द्वारा प्रदान की जा सकने वाली किसी भी मदद की सराहना करता हूं। धन्यवाद!

2
bp9 1 मई 2018, 03:58

1 उत्तर

सबसे बढ़िया उत्तर

strace का उपयोग करके सर्वर चलाकर, मैंने देखा कि यह poll() को POLLHUP ईवेंट लौटाते समय लूप में कॉल कर रहा था। समस्या यह थी कि आप G_IO_IN ईवेंट के लिए अनिश्चित काल तक प्रतीक्षा करने में सक्षम होने की उम्मीद करते हैं, यह बताने के लिए कि डेटा आ रहा है, लेकिन G_IO_HUP को प्रबंधित न करें जो आपको बताए कि कनेक्शन बंद था।

तब मुझे यह टिप्पणी bluez code:

if (cond & (G_IO_ERR | G_IO_HUP)) {
        /*
         * Both ends needs to be open simultaneously before proceeding
         * any input or output operation. When the remote closes the
         * channel, hup signal is received on this end.
         */
        fifo_open();
        return FALSE;
}

यह SO प्रश्न यह सब कुछ समझाता है: पाइप लगातार और तुरंत POLLHUP के साथ लौटता है

और यही मैंने strace के साथ देखा: जब क्लाइंट प्रक्रिया बाहर निकलती है (आपकी या आपके फीफो के लिए सिर्फ एक साधारण echo), IO चैनल को सूचित किया जाता है कि कनेक्शन का दूसरा पक्ष हैंग हो गया है। आपका क्लाइंट वर्तमान में एक संदेश भेजता है और कनेक्शन बंद कर देता है। तो या तो आप चाहते हैं कि यह कनेक्शन को जीवित रखे और डिस्कनेक्ट न करे, या आपको फीफो सर्वर-साइड को फिर से खोलने और एक नई घड़ी जोड़ने की जरूरत है, या जैसा कि मैंने लिंक किए गए SO प्रश्न में मार्क4ओ कहा है, आप फीफो को रीड/राइट राइट्स सर्वर-साइड के साथ खोलते हैं ताकि हैंग अप से बचने के लिए आपके पास फीफो (सर्वर) पर हमेशा कम से कम एक लेखक हो।

एक उदाहरण के रूप में, मैंने जिस ब्लूज़ कोड से लिंक किया है वह चैनल को बंद कर देता है और डिस्कनेक्शन पर एक नया खोलता है। अपने कोड पर संदर्भ गणना के मुद्दों का ध्यान रखने के लिए भी सावधान रहें।

1
liberforce 2 मई 2018, 16:28