2012-10-08 5 views

उत्तर

11

पहली कॉल 0 वापस आनी चाहिए; दूसरी कॉल -1 वापस करनी चाहिए, और errnoEBADF पर सेट करें।

आपको ज्ञात खराब संख्या में fd सेट करके दूसरी कॉल को रोकने से रोकना चाहिए, उदा। एक -1 तुरंत close की पहली कॉल के बाद, और बाद में fd दूसरी कॉल करने से पहले जाँच (और नहीं कॉल करने अगर fd-1 है):

close(fd); 
fd = -1; 
... 
// More code 
... 
if (fd != -1) { 
    close(fd) 
    fd = -1; 
} 

इस कोड पैटर्न में मदद मिलेगी जब आप करने के लिए कॉल करने के लिए की जरूरत है close एकाधिक स्थानों से, लेकिन आप सुनिश्चित नहीं हैं कि फ़ाइल खुली है, या यदि यह पहले से बंद कर दिया गया है। पासिंग -1 से close हानिरहित है (आपको निश्चित रूप से EBADF मिल जाएगा)।

+0

आपको दूसरे कॉल को होने से क्यों रोकना चाहिए? –

+0

एफडी से -1 सेट करना कोई प्रभाव नहीं पड़ता है (यह निश्चित रूप से "दूसरी कॉल को होने से रोकता नहीं है") ... दोनों और एक बंद एफडी उपज ईबीएडीएफ –

+5

@ जिमबाल्टर सेटिंग एफडी -1 -1 फ़ाइल को बंद करने के जोखिम से बचने के जोखिम से बच जाएगा, एक और धागा अभी खोला गया था। – simonc

7

यह हानिरहित जब तक आप पिरोया रहे हैं या दो कॉल के बीच कुछ कर बंद करने के लिए किया जाना चाहिए [एफडी एक पूर्णांक है]। फिर आप एक एफडी बंद कर सकते हैं कि आपके प्रोग्राम में कुछ और खोला गया है।

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

+0

+1 थ्रेडेड वातावरण में संभावित मुद्दों का उल्लेख करने के लिए +1। – alk

+0

* बंद करने के लिए पहले * कॉल किसी अन्य थ्रेड से एक एफडी बंद कर सकता है। दो बंद इस मुद्दे के लिए प्रासंगिक नहीं हैं। यहां थ्रेडिंग का एकमात्र तरीका प्रासंगिक है कि दूसरा एफडी फिर से खोलने के बाद असफल नहीं हो सकता है, लेकिन यह अनिच्छुक है ... यदि आप अपने धागे को सिंक्रनाइज़ नहीं करते हैं तो सभी प्रकार की बुरी चीजें हो सकती हैं। –

+2

'ओपन()' द्वारा वापस दिया गया मान ओएस द्वारा पुनर्नवीनीकरण किया जाता है। तो अगर थ्रेड ए को 'ओपन()' कहा जाता है और उसे fd = 3 मिला तो 'बंद करें)। फिर थ्रेड से पहले 'कॉल' (दूसरी बार 'दूसरी बार कॉल करता है, थ्रेड बी को' ओपन() 'सफलतापूर्वक बुलाया जाता है और फिर fd = 3 मिल जाता है। तो थ्रेड ए द्वारा बुलाया जाने वाला दूसरा 'क्लोज़()' क्या होगा? – alk

1

मूल्य पीएफ fd ही दूसरी कॉल एक त्रुटि वापस आ जाएगी कि fd मान्य नहीं है (EBADF - के रूप में dasblinkenlight ने बताया) रहता है

कर somthing की Think likg

if fd != -1) 
{ 
    close (fd); 
    fd = -1; 
} 
+1

इस तरह की चीज व्यर्थ है, क्योंकि बंद (एफडी) अनिर्धारित नहीं है या किसी भी तरह से खतरनाक है जब एफडी पहले से बंद हो गया है ... बंद (एफडी) और बंद (-1) बिल्कुल वही काम करते हैं। एफडी से -1 सेट करने का एकमात्र कारण यह सुनिश्चित करना है कि यह मान्य ओपन फाइल डिस्क्रिप्टर नहीं है जैसे 0. –

+0

ठीक है, लोगों ने ध्यान दिया है कि फ़ाइल डिस्क्रिप्टर किसी अन्य थ्रेड में फिर से खोला जा सकता है, इसलिए fd = -1 सेट करना अच्छा अभ्यास है। लेकिन 'fd! = -1' परीक्षण कड़ाई से जरूरी नहीं है ... इसके बिना प्रभाव समान है। –

+1

मैं आपसे सहमत हूं कि -1 के लिए परीक्षण की आवश्यकता नहीं है। और भी अधिक: एक डीबग-बिल्ड में मैं इसे छोड़ दूंगा, और त्रुटि को बंद करूँगा 'क्लोज़()' फिर वापस आ जाएगा, मुझे उस गड़बड़ी पर इंगित करने के लिए जो फ़ाइल को दो बार बंद करने का प्रयास करता है ... ;-) @ JimBalter – alk

3

दूसरी कॉल Errno: EBADF के साथ विफल हो जाएगी जब क्योंकि तब तक fd एक सक्रिय फ़ाइल वर्णनकर्ता नहीं है।

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

+0

आह, यह जवाब वास्तव में कुछ मान्य कहता है! +1 –

4

समापन ही एफडी दो बार गैर घातक होना चाहिए के रूप में अन्य लोगों ने बताया है, लेकिन यह

close(fd); 
/* ... */ 
newfd = open(....); 
/* ... */ 
close(fd); 

की तरह कोड से सावधान दूसरा पास रखकर आप यकीन है कि अगर fd वास्तव में है नहीं किया जा सकता newfd के समान! जब भी आप newfd का उपयोग करने का प्रयास करते हैं तो इससे क्रैश हो जाएंगे।

तो (यदि close कॉल दोनों के बीच कोड है) तो ऐसा करना सुरक्षित नहीं है। हमेशा close फाइल डिस्क्रिप्टर बिल्कुल एक बार।हमेशा free बफर बिल्कुल एक बार।

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