क्या लेखन शुरू होने पर या जब यह पूरा हो जाता है तो एक अधिसूचना को आग लगा देता है?


12

दो प्रक्रियाओं, एक पाठक और एक लेखक की कल्पना करें, एक ext3 fs पर एक नियमित फ़ाइल के माध्यम से संचार कर रहा है। रीडर के पास IN_MODIFYफ़ाइल पर एक इनोटिफ़ाइ वॉच है। राइटर सिंगल write()कॉल में फाइल को 1000 बाइट्स लिखता है । रीडर को इनॉटिफाई इवेंट मिलता है, और fstatफ़ाइल पर कॉल करता है। पाठक क्या देखता है?

  1. क्या कोई गारंटी है कि रीडर को st_sizeफ़ाइल पर कम से कम 1000 मिलेंगे ? मेरे प्रयोगों से, ऐसा नहीं लगता।

  2. क्या कोई गारंटी है कि पाठक वास्तव में read()1000 बाइट्स कर सकता है ?

यह गंभीरता से I / O बाउंड बॉक्स पर हो रहा है। उदाहरण के लिए, sarलगभग 1 सेकंड का प्रतीक्षा समय दिखाता है। मेरे मामले में पाठक वास्तव में 10 सेकंड के बाद प्रतीक्षा कर रहा है कि कॉल करने से पहले इनॉटिफाई इवेंट प्राप्त करें stat, और बहुत छोटे परिणाम प्राप्त करें।

मुझे क्या उम्मीद थी कि जब तक फ़ाइल तैयार नहीं हो जाती, तब तक इवेंट को वितरित नहीं किया जाएगा। मुझे जो वास्तव में संदेह हो रहा है, वह यह है कि इनॉटिफाई इवेंट write()लेखक में कॉल को दरकिनार करता है, और डेटा वास्तव में सिस्टम पर अन्य प्रक्रियाओं के लिए उपलब्ध होता है जब भी यह तैयार होता है। इस मामले में, 10s पर्याप्त समय नहीं है।

मुझे लगता है कि मैं सिर्फ इस बात की पुष्टि कर रहा हूं कि कर्नेल वास्तव में जिस तरह से अनुमान लगा रहा है उसे लागू करता है। इसके अलावा, अगर इस व्यवहार को बदलने के लिए कोई विकल्प हैं, तो संभवतः?

अंत में- इस व्यवहार को देखते हुए, क्या औचित्य की बात है? जब तक डेटा वास्तव में उपलब्ध न हो, तब तक आपको इवेंट मिलने के बाद फ़ाइल / निर्देशिका को पोलिंग करने के लिए कम कर दिया जाता है। के रूप में अच्छी तरह से हो सकता है कि सभी के साथ, और inotify भूल जाते हैं।

*** संपादित करें ** * * ठीक है, जैसा कि अक्सर होता है, जो व्यवहार मैं देख रहा हूं वह वास्तव में समझ में आता है, अब मैं समझता हूं कि मैं वास्तव में क्या कर रहा हूं। ^ _ ^

मैं वास्तव में उस फ़ाइल पर रहने वाली डायरेक्टरी पर एक IN_CREATE ईवेंट का जवाब दे रहा हूं। इसलिए मैं वास्तव में स्टेट () फाइल के निर्माण के जवाब में आईएनजी हूं, जरूरी नहीं कि IN_MODIFY ईवेंट हो, जो बाद में आ सकता है।

मैं अपना कोड बदलने जा रहा हूं, ताकि एक बार जब मुझे IN_CREATE ईवेंट मिल जाए, तो मैं फ़ाइल पर IN_MODIFY की सदस्यता लूंगा, और जब तक मुझे IN_MODIFY ईवेंट नहीं मिल जाता, तब तक मैं वास्तव में फ़ाइल को पढ़ने का प्रयास नहीं करूंगा। मुझे पता है कि वहाँ एक छोटी सी खिड़की है जिसमें मैं फ़ाइल को लिखने से चूक सकता हूं, लेकिन यह मेरे आवेदन के लिए स्वीकार्य है, क्योंकि सबसे खराब स्थिति में, फ़ाइल अधिकतम सेकंड के बाद बंद हो जाएगी।


आप एक फ़ाइल के बजाय एक पाइप का उपयोग कर सकते हैं। देखें मैन मकोड़
डैनियल कुल्मन 17

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

जवाबों:


5

मैं कर्नेल स्रोत में जो कुछ भी देखता हूं , उसमें से एक लिखने के पूरा होने के बाद ही फायर किया जाता है (यानी आपका अनुमान गलत है)। नोटिफिकेशन ट्रिगर होने के बाद, केवल दो और चीजें होती हैं sys_write, फ़ंक्शन जो कि writesyscall को लागू करता है : कुछ शेड्यूलर पैरामीटर सेट करना, और फ़ाइल डिस्क्रिप्टर पर स्थिति को अपडेट करना। यह कोड 2.6.14 के समान वापस आ गया है । जब तक सूचना फायर करती है, तब तक फ़ाइल पहले से ही अपना नया आकार लेती है।

उन चीजों की जाँच करें जो गलत हो सकती हैं:

  • हो सकता है कि पिछले लेखन से पाठक को पुरानी सूचनाएं मिल रही हों।
  • यदि पाठक कॉल करता है statऔर फिर कॉल करता है readया इसके विपरीत, बीच में कुछ हो सकता है। यदि आप फ़ाइल से जुड़ना जारी रखते हैं, तो statपहले गारंटी देते हुए कि आप उस तक को पढ़ पाएंगे, लेकिन यह संभव है कि पाठक द्वारा कॉल किए जाने के समय तक अधिक डेटा लिखा गया हो read, भले ही यह अभी तक इनॉटिफाई नोटिफिकेशन प्राप्त नहीं किया हो।
  • सिर्फ इसलिए कि लेखक कॉल का writeमतलब यह नहीं है कि कर्नेल अनुरोधित वर्णों की संख्या लिख ​​देगा। बहुत कम ही परिस्थितियाँ ऐसी होती हैं जहाँ परमाणु लेखन को किसी भी आकार तक की गारंटी दी जाती है। प्रत्येक writeकॉल परमाणु की गारंटी है, हालांकि: कुछ बिंदु पर डेटा अभी तक नहीं लिखा गया है, और फिर अचानक n बाइट्स लिखा गया है, जहां nwrite कॉल का वापसी मूल्य है । यदि आप आंशिक रूप से लिखित फ़ाइल का निरीक्षण करते हैं, तो इसका मतलब है कि writeउसके आकार के तर्क से कम लौटा है।

जांच के लिए उपयोगी उपकरण क्या शामिल हैं:

  • strace -tt
  • लेखा परीक्षा उपतंत्र

विचारों के लिए धन्यवाद। मैंने अभी कोड की समीक्षा की है, और मैं वास्तव में केवल -1 के लिए जाँच कर रहा हूं क्योंकि त्रुटि मामले के लिए लिखने से वापसी मूल्य। तो, यह हो सकता है कि मुझे लिखने से रिटर्न वैल्यू नहीं मिल रहा है यह दर्शाता है कि सभी डेटा लिखा गया था। फिर भी, जब मैं इस तथ्य के बाद फाइल को देखता हूं, तो मुझे पता है कि सभी "1000" बाइट्स वास्तव में लिखे गए थे, क्योंकि फाइल अच्छे आकार में है, अर्थात इसमें संपूर्ण, सुसंगत रिकॉर्ड शामिल हैं। इसलिए पहला रिकॉर्ड आंशिक रूप से नहीं लिखा जा रहा है।
टॉड फ्रीड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.