C语言 使用 nftw 时如何避免使用全局变量



我想使用 nftw 遍历 C 语言中的目录结构。

但是,鉴于我想做的事情,我看不到使用全局变量的方法。

使用(n)ftw的教科书示例都涉及打印文件名之类的操作。 相反,我想获取路径名和文件校验和,并将它们放在数据结构中。 但是鉴于可以传递给 nftw 的内容的限制,我认为没有好方法可以做到这一点。

我使用的解决方案涉及全局变量。 然后,nftw 调用的函数可以访问该变量并添加所需的数据。

有没有合理的方法可以在不使用全局变量的情况下做到这一点?

这是上一篇文章中关于stackoverflow的交流,有人建议我将其作为后续发布。

使用 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。

如果您仍然想使用 nftw,那么我的建议是将"全局"类型放在命名空间中并将其标记为"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;
}

数据最好在一个单独的模块中给出静态链接(即文件范围),该模块仅包含访问数据所需的函数,包括传递给nftw()的函数。 这样,数据就不全局可见,并且所有访问都受到控制。 调用 ntfw() 的函数也可能是该模块的一部分,这使得传递给 nftw() 的函数也是静态的,因此在外部不可见。

换句话说,你应该做你可能已经在做的事情,但明智地使用单独的编译和静态链接,使数据只能通过访问函数可见。 具有静态链接的数据可由同一翻译单元中的任何函数访问,并且通过仅包含该翻译单元中作为该数据的创建者、维护者或访问者的函数来避免与全局变量相关的问题。

一般模式是:

数据模块.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
}

No. nftw 不提供任何可以传递给函数的用户参数,因此您必须在 C 中使用全局(或静态)变量。

GCC 提供了一个扩展"嵌套函数",它应该捕获其封闭作用域的变量,因此它们可以像这样使用:

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

相关内容

  • 没有找到相关文章

最新更新