2012-04-23 4 views
7

मैं nftw उपयोग करने के लिए सीकैसे जब nftw

हालांकि, यह देखते हुए कि मैं क्या करना चाहते हैं में एक निर्देशिका संरचना पार करने के लिए चाहते हैं का उपयोग कर वैश्विक चर का उपयोग कर से बचने के लिए मैं एक वैश्विक चर का उपयोग कर के चारों ओर एक रास्ता नहीं दिख रहा।

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

मैं जिस समाधान का उपयोग कर रहा हूं वह वैश्विक चर शामिल है। Nftw द्वारा बुलाया गया फ़ंक्शन उस चर को एक्सेस कर सकता है और आवश्यक डेटा जोड़ सकता है।

क्या वैश्विक चर का उपयोग किए बिना ऐसा करने का कोई उचित तरीका है?

Here's the exchange in previous post on stackoverflow in which someone suggested I post this as a follow-up.

उत्तर

2

सं nftw किसी भी उपयोगकर्ता पैरामीटर है कि कार्य करने के लिए पारित किया जा सकता है प्रदान नहीं करता है, तो आप सी

में वैश्विक (या स्थिर) चर का उपयोग करने के लिए

जीसीसी एक विस्तार "प्रदान करता है नेस्टेड समारोह "जो उनके enclosing स्कोप के चर पर कब्जा करना चाहिए, ताकि वे इस तरह इस्तेमाल किया जा सकता:

void f() 
{ 
    int i = 0; 
    int fn(const char *, 
    const struct stat *, int, struct FTW *) { 
    i++; 
    return 0; 
    }; 
    nftw("path", fn, 10, 0); 
} 
1

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

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

datamodule.h

#if defined DATAMODULE_INCLUDE 
<type> create_data(<args>) ; 
<type> get_data(<args>) ; 
#endif 

datamodule.c

#include "datamodule.h" 

static <type> my_data ; 

static int nftwfunc(const char *filename, const struct stat *statptr, int fileflags, struct FTW *pfwt) 
{ 
    // update/add to my_data 
    ... 
} 


<type> create_data(const char* path, <other args>) 
{ 
    ... 

    ret = nftw(path, nftwfunc, fd_limit, flags); 

    ... 
} 

<type> get_data(<args>) 
{ 
    // Get requested data from my_data and return it to caller 
} 
+0

मैं, के बाद से बीएसडी पुस्तकालय "libarchive" (जो मैं भी उपयोग कर रहा हूँ) कि जिस तरह से सेट किया गया है कोड अलगाव की बहुत बनाने की खूबियों के बारे में पता था। लेकिन आपकी टिप्पणी ने इस मुद्दे को मजबूत करने में मदद की, और परिणामस्वरूप मैं स्थैतिक कीवर्ड का अधिक उपयोग करूँगा। (अगर मैं कर सकता हूं तो आपको ऊपर उठाऊंगा।) – user1071847

+1

[ग्लोबल्स पर पॉक्स] (http://www.eetimes.com/discussion/break-point/4025723/A-pox-on-globals) आलेख मैंने आपकी पिछली पोस्ट में लिंक किया था इस तकनीक पर भी चर्चा करता है। यह आलेख एम्बेडेड सिस्टम को संदर्भित करता है, लेकिन यह सामान्य उद्देश्य कंप्यूटिंग पर कम लागू नहीं है। मैं यह भी सुझाव दूंगा कि सी ++ आपको कक्षाओं और नामस्थानों के उपयोग से बेहतर डेटा encapsulation के लिए और अवसर प्रदान करता है। इस तरह से स्थैतिक उपयोग के बारे में कुछ सावधानी, यह ठीक है अगर आपको केवल डेटा के एक उदाहरण की आवश्यकता होती है, और इसके परिणामस्वरूप गैर-पुनर्विक्रेता और गैर थ्रेड-सुरक्षित कोड होता है। अन्य समाधान लागू हो सकते हैं। – Clifford

1

FTW का उपयोग वास्तव में हो सकता है,:

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

डरावना परिदृश्य:

thread 1: count billions of files 
thread 2: delete some files 
thread 1: ---oops, it is now deleting billions of 
       files instead of counting them. 

संक्षेप में। आप fts_open का उपयोग कर बेहतर कर रहे हैं।

यदि आप अभी भी एनएफटीडब्ल्यू का उपयोग करना चाहते हैं तो मेरा सुझाव है कि "वैश्विक" प्रकार को नामस्थान में डालें और इसे "thread_local" के रूप में चिह्नित करें।आपको अपनी आवश्यकताओं के अनुसार इसे समायोजित करने में सक्षम होना चाहिए।

/* in some cpp file */ 
namespace { 
    thread_local size_t gTotalBytes{0}; // thread local makes this thread safe 
int GetSize(const char* path, const struct stat* statPtr, int currentFlag, struct FTW* internalFtwUsage) { 
    gTotalBytes+= statPtr->st_size; 
    return 0; //ntfw continues 
} 
} // namespace 


size_t RecursiveFolderDiskUsed(const std::string& startPath) { 
    const int flags = FTW_DEPTH | FTW_MOUNT | FTW_PHYS; 
    const int maxFileDescriptorsToUse = 1024; // or whatever 
    const int result = nftw(startPath.c_str(), GetSize, maxFileDescriptorsToUse , flags); 

    // log or something if result== -1 
    return gTotalBytes; 
} 
+0

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

+0

... लेकिन fts ftw से कम व्यापक है। – fche