क्या एक प्रक्रिया से बाहर निकलने पर बफर स्वचालित रूप से डिस्क में फ्लश हो जाएगा?


21

जब मैं किसी कमांड के आउटपुट को किसी फ़ाइल (जैसे echo Hello > file) में रीडायरेक्ट करता हूं, तो क्या कमांड से बाहर निकलने के बाद उस फाइल को इस तरह के डेटा की गारंटी दी जाएगी? या क्या कमांड एक्ज़िट और फ़ाइल में लिखे डेटा के बीच अभी भी बहुत छोटी खिड़की है? मैं कमांड से बाहर निकलने के ठीक बाद फाइल पढ़ना चाहता हूं, लेकिन मैं खाली फाइल नहीं पढ़ना चाहता।


1
यह शायद आदेश निष्पादित करता है सही दूर है, लेकिन समय की राशि यह वास्तव में फ़ाइल, लिखने को खोलने के लिए लेता है, और पास की गति और अपनी हार्ड ड्राइव, किसी भी चल रहे कार्यक्रम, आदि के प्रकार पर निर्भर करेगा
freginold

दिए गए उदाहरण के संदर्भ में, 'प्रक्रिया' क्या है? कर रहे हैं echoऔर >न अलग (अल्पकालिक) प्रक्रियाओं? और echoपहले >निष्पादित किए जाने का आउटपुट कहाँ रहता है?
o

1
@ o @ >शेल पुनर्निर्देशन है। यह वैसा ही है जैसे कि प्रोग्राम ने लिखने के लिए नामित फ़ाइल को खोल दिया था और इसके साथ stdout को बदल दिया था जो वास्तव में शेल करता है।
डैन डी।

7
मुझे लगता है कि आप देने के लिए ओएस जिम्मेदारी है fileयुक्त Helloचाहे वह प्लावित है या नहीं की परवाह किए बिना।
सलमान ए

1
यदि प्रोग्राम मशीन ए पर चल रहा है, और आप मशीन बी पर फाइल पढ़ रहे हैं, मशीन ए के फाइल सिस्टम के साथ नेटवर्क पर माउंट किया जाता है, तो आप नेटवर्क फाइल सिस्टम प्रकार और माउंट सेटिंग्स के आधार पर एक खाली फाइल को पढ़ सकते हैं। तो आप उस माउंट के लिए कैशिंग को अक्षम करना चाह सकते हैं।
अंक

जवाबों:


21

इसमें बफ़र्स / कैश की कई परतें शामिल हैं।

  1. सीपीयू कैश।

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

  2. इन-प्रोसेस बफ़र्स।

    इस प्रक्रिया में एक तरफ कुछ मेमोरी सेट होती है, जहां डेटा एकत्र किया जाता है, इसलिए हमें यथासंभव ओएस के लिए कुछ अनुरोध करने की आवश्यकता है, क्योंकि यह तुलनात्मक रूप से महंगा है। प्रक्रिया इन बफ़र्स को डेटा की प्रतिलिपि बनाती है, जो फिर से सीपीयू कैश द्वारा समर्थित हो सकती है, इसलिए कोई गारंटी नहीं है कि डेटा को मुख्य मेमोरी में कॉपी किया गया है। इन बफ़र्स को स्पष्ट रूप से फ्लश करने के लिए एप्लिकेशन की आवश्यकता होती है, उदाहरण के लिए fclose (3) या fsync (3) का उपयोग करना। बाहर निकलने (3) फ़ंक्शन प्रक्रिया समाप्त होने से पहले भी ऐसा करता है, जबकि _exit (2) फ़ंक्शन नहीं करता है , यही कारण है कि उस फ़ंक्शन के लिए मैन्युअल पेज में एक बड़ी चेतावनी है केवल इसे कॉल करने के लिए यदि आप जानते हैं कि आप क्या हैं करते हुए।

  3. गिरी बफ़र्स

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

  4. ड्राइव कैश

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

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


7
सीपीयू कैशिंग पर विचार करना मेरे लिए प्रासंगिक नहीं है। यह यहाँ विस्तार का एक अनावश्यक स्तर है। जैसा कि सभी विवरणों से गुजर रहा है जब तक कि कुछ भौतिक मात्रा एक हार्ड डिस्क प्लैटर या एसएसडी मेमोरी पर थोड़ा सा प्रतिनिधित्व करती है, इसे बदलने के लिए बदल दिया जाता है।
mvw

3
दरअसल, सीपीयू कैश काफी ओर्थोगोनल है।
साइमन रिक्टर

2
और अधिक महत्वपूर्ण बात, सीपीयू कैश कोर के बीच सुसंगत है, यही कारण है कि यह पूरी तरह से तस्वीर से बाहर है। X86 पर, यह डीएमए के साथ भी सुसंगत है (और x86 के पास कुल-स्टोर-ऑर्डर मेमोरी-ऑर्डरिंग मोड है), इसलिए कुछ भी जो मेमोरी पढ़ सकता है वह डेटा को हाल ही में मेमोरी ऑपरेशन के वैश्विक क्रम में उस पते पर संग्रहीत देखेंगे। (एक CPU कोर अपने स्वयं के स्टोर को तब भी देखेगा, जब तक कि वह विश्व स्तर पर दृश्यमान नहीं हो जाता, क्योंकि स्टोर कतार से स्टोर-फ़ॉरवर्डिंग)। कैश-सुसंगत डीएमए के बिना गैर- x86 प्लेटफार्मों पर, लिनक्स कर्नेल सुनिश्चित करता है कि कैश उन पते पर डीएमए से पहले फ्लश किया जाता है।
पीटर कॉर्डेस

1
"ये, अधिकांश भाग के लिए, एप्लिकेशन प्रोग्रामर से छिपाए गए हैं।" क्यों "अधिकांश भाग के लिए"? मैं एक एम्बेडेड डेवलपर हूं और बूट लोडर के दौरान (इसलिए "एप्लिकेशन" नहीं) को छोड़कर मैं पूरी तरह से सीपीयू कैश की उपेक्षा करता हूं। मुझे नहीं लगता कि कोई भी एप्लिकेशन डेवलपर CPU कैश के प्रभाव से प्रभावित हो सकता है।
सैम

1
@ सॅम कैश मिस / हिट्स सट्टा निष्पादन के साथ कुछ सीपीयू में उपयोग किया जा सकता है रीड एक्सेस प्रतिबंध को बायपास करने के लिए। शायद यही बात उत्तर की ओर इशारा करती है?
जॉन ड्वोरक

22

यदि एप्लिकेशन में कोई आंतरिक कैश नहीं है, तो परिवर्तन तुरंत फ़ाइल में लिखा जाएगा। अपने उदाहरण के लिए भी ऐसा ही है। फ़ाइल स्मृति में एक तार्किक इकाई है जिसे तुरंत अपडेट किया जाएगा। फ़ाइल के बाद के किसी भी ऑपरेशन को प्रोग्राम द्वारा किए गए परिवर्तनों को देखेंगे।

हालांकि , इसका मतलब यह नहीं है कि परिवर्तन भौतिक डिस्क पर लिखा गया था। परिवर्तन ओएस फाइलसिस्टम कैश या हार्डवेयर कैश में डूब सकते हैं। फाइलसिस्टम बफ़र्स को फ्लश करने के लिए, syncकमांड का उपयोग करें ।

मैं कमांड से बाहर निकलने के ठीक बाद फाइल पढ़ना चाहता हूं, लेकिन मैं खाली फाइल नहीं पढ़ना चाहता।

आपको यहां किसी भी व्यावहारिक समस्या में नहीं चलना चाहिए।


1
"यदि एप्लिकेशन में कोई आंतरिक कैश नहीं है" - तो यह एक बहुत बड़ी "यदि" है: I / O लाइब्रेरी कार्यान्वयन के विशाल बहुमत डिफ़ॉल्ट रूप से बफर स्टडआउट का उपयोग करते हैं। उदाहरण के लिए, C मानक यह कहता है कि stdout बफर बाहर निकलने पर फ्लश हो जाता है (लेकिन संभवतः नहीं तो exitकम से कम अंतर्निहित रूप से नहीं कहा जाता है)। अन्य पुस्तकालयों / भाषाओं (जैसे जावा!) कम गारंटी देते हैं।
कोनराड रुडोल्फ

क्या होगा अगर सिर्फ इसे रीडायरेक्ट प्रिमिटिव तक सीमित कर दिया जाए (यानी, मेरे प्रश्न में कमांड)? यह आंतरिक कैश नहीं है, है ना?
एरिक

@ एरिक नहीं, आपको ठीक होना चाहिए।
मटक

10
मुझे यकीन नहीं है कि मुझे यह जवाब मिलेगा। सवाल "जब प्रक्रिया से बाहर निकलता है" के बारे में है। आंतरिक लेखन कैश के साथ हर एप्लिकेशन उन्हें प्रक्रिया से बाहर निकलने के लिए डिस्क में फ्लश करेगा, अगर ऐसा पहले नहीं हुआ था। IOW, उन कैश को यहां कोई फर्क नहीं पड़ता।
MSalters

2
इसके अलावा, एक आंतरिक बफर या तो बाहर निकल जाएगा या सिर्फ अस्तित्व से फीका हो जाएगा, है ना? इसलिए भले ही आंतरिक बफ़र्स फ्लश न करें, लेकिन यह सामग्री देखने योग्य नहीं होगी, चाहे वह कितनी भी लंबी प्रतीक्षा करे।
WorldSEnder

21

क्या एक प्रक्रिया से बाहर निकलने पर बफर स्वचालित रूप से डिस्क में फ्लश हो जाएगा?

सामान्य तौर पर उत्तर नहीं है

यह कमांड पर निर्भर करता है। जैसा कि अन्य उत्तर में उल्लेख किया गया है, यदि कमांड आंतरिक रूप से डेटा को बफर नहीं करता है, कमांड समाप्त होने पर सभी डेटा उपलब्ध होंगे।

लेकिन अधिकांश, यदि सभी नहीं, तो मानक I / O लाइब्रेरी डिफ़ॉल्ट रूप से (कुछ हद तक) बफर स्टैडआउट करते हैं , और एप्लिकेशन बंद होने पर बफ़र्स के स्वत: फ्लशिंग के बारे में अलग-अलग गारंटी देते हैं।

सी गारंटी देता है कि एक सामान्य निकास बफ़र्स को बहा देगा । "सामान्य निकास" का मतलब है कि exitकहा जाता है - या तो स्पष्ट रूप से, या से लौटकर main। हालाँकि, असामान्य निकास इस कॉल को दरकिनार कर सकता है (और इसलिए अप्रभावित बफ़र्स को पीछे छोड़ देता है)।

यहाँ एक सरल उदाहरण दिया गया है:

#include <signal.h>
#include <stdio.h>

int main() {
    printf("test");
    raise(SIGABRT);
}

यदि आप इसे संकलित करते हैं और इसे निष्पादित करते हैं, testतो जरूरी नहीं कि इसे stdout को लिखा जाएगा।

अन्य प्रोग्रामिंग भाषाएं भी कम गारंटी देती हैं: उदाहरण के लिए, जावा प्रोग्राम समाप्ति पर ऑटो-फ्लश नहीं करता है । यदि आउटपुट बफ़र में एक असंबद्ध रेखा होती है, तो इसलिए इसे खो दिया जा सकता है, जब तक System.out.flush()कि इसे स्पष्ट रूप से नहीं कहा जाता।

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


7
मैंने असामान्य निकास भी देखा है जब एक कमांड-लाइन टूल किसी फ़ाइल पर और डीबग लॉग की तरह stdout या stderr को लिख रहा है, और उपयोगकर्ता ने पाइप को कम या कम करने के लिए टाइप किया है और 'q' टाइप करने के लिए कम छोड़ दिया है। यदि कमांड-लाइन टूल SIGPIPE को हैंडल नहीं करता है, तो डिस्क फ़ाइल हमेशा पूरी तरह से फ्लश नहीं होती है।
ज़ैन लिंक्स

+1, लेकिन " कमांड समाप्त होने के तुरंत बाद ऐसा करना चाहिए" यह बिल्कुल सही नहीं है: प्रक्रिया से बाहर निकलने से पहले कोई भी write()या pwrite()सिस्टम कॉल होगा , और यह तब होता है जब फ़ाइल परिवर्तन दिखाई देते हैं। तो अंतिम फ़ाइल परिवर्तन निश्चित रूप से प्रक्रिया समाप्ति से पहले है, नवीनतम में तुरंत-पहले। मुझे लगता है कि एक फ़ाइल के साथ भी , प्रक्रिया समाप्ति का निरीक्षण करने के लिए कुछ भी करने का कोई तरीका नहीं है इससे पहले कि सभी फ़ाइल परिवर्तन होने वाले हैं। mmap(MAP_SHARED)
पीटर कॉर्डेस

9

मुझे लगता है कि कोई भी सवाल इस मुद्दे को पर्याप्त रूप से संबोधित नहीं करता है:

मैं कमांड से बाहर निकलने के ठीक बाद फाइल पढ़ना चाहता हूं, लेकिन मैं खाली फाइल नहीं पढ़ना चाहता।

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

यह आमतौर पर प्रति फ़ाइल ऑब्जेक्ट में अधिकांश एक-इन-कर्नेल बफर में होने और इस बफर के माध्यम से जाने के लिए सभी फ़ाइल एक्सेस की आवश्यकता होती है।

  • यदि कोई प्रक्रिया किसी फ़ाइल को पढ़ती है, तो कर्नेल प्रक्रिया में बफर सामग्री को प्रस्तुत करेगा, यदि अनुरोधित फ़ाइल भाग वर्तमान में बफर में है; यदि यह नहीं है, तो कर्नेल अंतर्निहित भंडारण माध्यम से डेटा प्राप्त करेगा और इसे बफर के अंदर रखेगा, फिर पिछले चरण पर वापस जाएं।

  • यदि कोई प्रक्रिया किसी फ़ाइल को लिखती है, तो डेटा को पहले उस फ़ाइल के लिए इन-कर्नेल बफर के अंदर रखा जाता है। आखिरकार बफर सामग्री को भंडारण में प्रवाहित किया जाएगा। मतलब समय में रीड एक्सेस एक ही बफर से संतुष्ट है (ऊपर देखें)।


1 कम से कम नियमित फ़ाइलों, निर्देशिकाओं और प्रतीकात्मक लिंक के लिए। एफआईएफओ और सॉकेट एक अलग मामला है क्योंकि उनकी सामग्री को कभी भी लगातार संग्रहीत नहीं किया जाता है। नियमित फ़ाइलों के कुछ विशेष मामले हैं जिनकी सामग्री इस बात पर निर्भर करती है कि कौन पूछ रहा है; उदाहरण procfs और sysfs में फाइलें हैं (सोचें कि /proc/selfजो प्रतीकात्मक लिंक पढ़ने की प्रक्रिया की आईडी का प्रतीकात्मक लिंक है)।


2
कड़ाई से बोलते हुए, यह लिनक्स का फाइलसिस्टम शब्दार्थ नहीं है जो इसकी गारंटी देता है, यह पॉसिक्स शब्दार्थ है। विशेष रूप से, बीएसडी बिल्कुल वैसा ही व्यवहार करता है, जैसा कि मैकओएस करता है, और यहां तक ​​कि विंडोज (हालांकि यह उन कुछ मामलों में से एक है जहां विंडोज पॉसिक्स शब्दार्थ का अनुसरण करता है)। यह mmap()और O_DIRECT के साथ किसी के भी अजीब सामान को ग्रहण नहीं करता है , जिसके कारण डिस्क और पेज कैश के बीच चीजें आउट-ऑफ-सिंक हो सकती हैं (लेकिन यह उस पल को हल कर देगा जो उस प्रक्रिया से बाहर निकलता है)।
ऑस्टिन हेमेलर्गरन

2
@AustinHemmelgarn: सख्ती से बोलना हम दोनों सही कह रहे हैं क्योंकि लिनक्स को यूनिक्स (सिस्टम V) अनुप्रयोगों को ध्यान में रखते हुए डिज़ाइन किया गया था और बाद में POSIX का समर्थन करने के लिए बनाया गया, जो सिस्टम V पर कई अवधारणाओं को भी आधार बनाता है
डेविड फ़ॉस्टर

5

सी रनटाइम लाइब्रेरी का उपयोग करके कुछ प्रोग्राम द्वारा आपकी कमांड को निष्पादित किया जाता है, कुछ बिंदु पर इसे fcloseखुली फाइल को बंद करने के लिए आह्वान करना चाहिए ।

fcloseC फ़ंक्शन का मैन पेज कहता है:

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

और जिस आदमी के पेज के लिए fflushएक ही नोट है। वह आदमी पेज closeकहता है:

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

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

यदि आप संदेह में हैं, तो एक परीक्षण लिखें।


2
C या नहीं, सब कुछ close()फ़ाइल के डिस्क्रिप्टर को बंद करने के लिए syscall का उपयोग करना चाहिए ।
Attie

@Attie: आप नहीं है की जरूरत करने के लिए closeबाहर निकलने (hacky प्रोग्राम हैं जो त्रुटियों की जांच नहीं करते हैं) से पहले फ़ाइलों; कर्नेल उन्हें साफ करेगा, प्रभावी रूप से closeआपकी प्रक्रिया के बाद आपके लिए बुलाएगा। आपको fcloseकिसी भी बफर स्ट्रीओ स्ट्रीम की जरूरत है , हालांकि, या exit(3)एग्जिट कॉल के विपरीत, सीधे आपके साथ ऐसा करने के लिए libc करते हैं।
पीटर कॉर्डेस

यदि आप संदेह में हैं, तो एक परीक्षण लिखें। यह दौड़ की स्थिति का पता लगाने के लिए बुरी सलाह है। हार्डवेयर के एक टुकड़े पर चलने वाले एक कर्नेल पर परीक्षण आपको बता सकता है कि दौड़ उस सिस्टम पर आपके परीक्षण द्वारा उत्पादित सॉफ़्टवेयर स्थितियों के तहत नहीं हो सकती है, या यदि यह पता लगाने के लिए बहुत दुर्लभ है। लेकिन यह आपको नहीं बता सकता है कि क्या यह व्यवहार सभी फाइल सिस्टम, गुठली और सभी हार्डवेयर (जैसे पावरपीसी) में सुरक्षित माना जाता है। यानी आप यह नहीं बता सकते हैं कि आप जिस गारंटी पर निर्भर हैं, वह कार्यान्वयन विवरण है या जानबूझकर भविष्य-प्रमाण की गारंटी है! (इस मामले में यह है।)
पीटर कॉर्ड्स

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

3

जब मैं किसी कमांड के आउटपुट को किसी फ़ाइल (जैसे echo Hello > file) में रीडायरेक्ट करता हूं, तो क्या कमांड से बाहर निकलने के बाद उस फाइल को इस तरह के डेटा की गारंटी दी जाएगी?

हाँ। खोल आउटपुट-फाइल को खोलता है, और echoआउटपुट सीधे उसी को देता है। आदेश से बाहर निकलने के बाद, यह किया जाता है।

या क्या कमांड एक्ज़िट और फ़ाइल में लिखे डेटा के बीच अभी भी बहुत छोटी खिड़की है?

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

मैं कमांड से बाहर निकलने के ठीक बाद फाइल पढ़ना चाहता हूं, लेकिन मैं खाली फाइल नहीं पढ़ना चाहता।

चिंता न करें, कर्नेल केवल फ़ाइल का एक दृश्य रखता है, जिसे कितनी बार खोला गया है, स्वतंत्र है।


"कर्नेल केवल फ़ाइल का एक दृश्य रखता है": के लिए बिल्कुल सच नहीं हैmmap(MAP_SHARED) : mmaped क्षेत्र में स्टोर फ़ाइल की रीड (उस थ्रेड या अन्य प्रक्रियाओं द्वारा) के साथ सुसंगत नहीं हैं। यही कारण है कि msync(2)मौजूद है। कम से कम यही है कि आदमी पृष्ठों के बारे में चेतावनी देता है; कार्यान्वयन के आधार पर, लिनक्स वास्तव में पेजकेस से भौतिक पृष्ठों को मैप कर सकता है, जिस स्थिति में मुझे लगता है कि यह मूल रूप से सुसंगत है (मॉडुलो मेमोरी-ऑर्डरिंग)। वैसे भी, यह सब पहले भी होता है _exit(2)
पीटर कॉर्डेस

2

एक सामान्य नियम के रूप में, कर्नेल के स्वामित्व वाले किसी भी डेटा को कर्नेल, अवधि द्वारा बनाए रखा और साफ किया जाता है। इस तरह के डेटा में सिस्टम कॉल जैसे कर्नेल मेमोरी में ट्रांसफर किया गया डेटा शामिल होता है write(2)

हालाँकि, यदि आपका एप्लिकेशन (उदाहरण C लाइब्रेरी) इस के शीर्ष पर बफरिंग करता है , तो कर्नेल को स्पष्ट रूप से कोई पता नहीं है और इसलिए इसकी सफाई की गारंटी नहीं है।

इसके अलावा, मुझे विश्वास नहीं है कि क्लीन-अप के लिए कोई समय की गारंटी है - यह, सामान्य रूप से, "सर्वश्रेष्ठ-प्रयास" (पढ़ें: "जब मेरे पास एक सेकंड होता है") के आधार पर प्रदर्शन किया जाता है।


इस बात की गारंटी है कि कोई भी क्लीनअप / बफर-फ्लशिंग एक पेरेंट प्रोसेस के waitpid()रिटर्न से पहले होगा , अगर क्लीनअप बिल्कुल भी होता है। अर्थात अन्य प्रक्रियाएं उस प्रक्रिया द्वारा किए गए किसी भी फ़ाइल संशोधन से पहले होने वाली प्रक्रिया समाप्ति को सीधे नहीं देख सकती हैं। (मैंने कहा कि "सीधे" एनएफएस फ़ाइल टाइमस्टैम्प के माध्यम से अप्रत्यक्ष अवलोकन को नियंत्रित करने के लिए, क्योंकि एनएफएस कैशिंग मेजबानों के बीच पूरी तरह से सुसंगत नहीं है।)
पीटर कॉर्ड्स

@PeterCordes: मुझे लगता है कि यह "रखरखाव" के विपरीत "क्लीन-अप" से आपका मतलब है। मेरे लिए "बनाए रखना" "एक सुसंगत दृश्य प्रदान करना" (जिसमें आपके द्वारा बताई गई गारंटी है) और "क्लीन अप" "डिस्क से फ्लश" है, जो मुझे नहीं लगता कि एक समय की गारंटी है।
मेहरदाद

ओह, मैं देख रहा हूं, आप सवाल का "फ्लशेड टू डिस्क" जवाब दे रहे हैं, जो बाद में प्रक्रियाओं को देखने के लिए अप्रासंगिक है जो फ़ाइल को पढ़ते समय दिखाई देगा। "मैली आई / ओ कैश / बफर मेमोरी क्लीन" के अर्थ में "क्लीन अप"। जब तक आप fsync/ का उपयोग नहीं करते हैं fdatasync, तब तक कोई सही समय की गारंटी नहीं है , हालांकि लिनक्स पर बफर राइट-बैक /proc/sys/vm/dirty_writeback_centisecsएक सेकंड के सौवें के बाद शुरू होगा (यदि अन्य I / O ट्रैफ़िक में देरी नहीं हुई है), और उस खरीद निर्देशिका में विभिन्न अन्य ट्यूनल्स भी चीजों को प्रभावित करते हैं (जैसे कैसे किसी भी लिखने के पीछे करने से पहले बफ़र्स को बड़े होने देना)।
पीटर कॉर्डेस

2

या क्या कमांड एक्ज़िट और फ़ाइल में लिखे डेटा के बीच अभी भी बहुत छोटी खिड़की है?

नहीं, वहाँ नहीं है।

मैं कमांड से बाहर निकलने के ठीक बाद फाइल पढ़ना चाहता हूं, लेकिन मैं खाली फाइल नहीं पढ़ना चाहता।

कमांड के बाहर निकलते ही आप फ़ाइल की अंतिम सामग्री पढ़ सकते हैं, इसके बजाय आप कभी भी खाली फ़ाइल नहीं पढ़ पाएंगे। (में C और C ++, का उपयोग इंतजार , waitpid , wait3 या wait4 बाहर निकलने के लिए कार्यक्रम के लिए प्रतीक्षा करने प्रणाली निरिक्षण और उसके बाद ही फाइल पढ़ने। यदि आप एक खोल, एक और प्रोग्रामिंग भाषा या एक पुस्तकालय (जैसे C लाइब्रेरी का उपयोग कर रहे हैं, तो कॉल सिस्टम या जावा प्रोसेस क्लास), यह संभवत: इनमें से किसी एक सिस्टम कॉल का उपयोग करता है।)

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


0

हाँ

शायद एक और शानदार जवाब जोड़ने के लिए क्षमा करें, लेकिन सबसे अधिक सवाल के शीर्षक के लाल हेरिंग पर ध्यान केंद्रित करने के लिए लगता है। लेकिन जहाँ तक मैं बता सकता हूँ, सवाल बफ़रिंग का नहीं है, बल्कि यह है:

जब मैं किसी फ़ाइल में कमांड के आउटपुट को रीडायरेक्ट करता हूं (जैसे, हैलो नमस्ते> फ़ाइल) तो क्या कमांड के बाहर निकलने के बाद फ़ाइल को इस तरह के डेटा की गारंटी दी जाएगी?

हाँ, बिना शर्त। ">" का उपयोग जो आप वर्णन कर रहे हैं, साथ में "|" और "<", पाइप-आधारित प्रसंस्करण मॉडल है जो यूनिक्स और लिनक्स दुनिया पर आधारित है। यदि आप प्रत्येक लिनक्स इंस्टॉलेशन में इस व्यवहार पर निर्भर करते हैं, तो आपको सैकड़ों स्क्रिप्ट नहीं मिलेंगी।

यह डिजाइन के अनुसार काम करता है, और अगर दौड़ की स्थिति की थोड़ी सी भी संभावना है, तो यह शायद दशकों पहले तय किया गया होगा।


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