C线程文件系统操作:ftw()或fts_open()?

时间:2018-05-24 05:34:05

标签: c file unix directory filesystems

假设一个线程程序正在执行文件系统操作(遍历,读取,创建,删除,移动目录和文件)。

根据an answerftw()在这种情况下不安全。 (另外,ftw()需要全局变量,这看起来并不太优雅。)

我应该使用fts_open() / fts_children() / fts_read()吗?或许scandir()

使用ftw()(某些线程正在使用ftw()来聚合数据而另一个线程正在删除/移动某些数据)的线程程序是不安全的,确切地说,为什么?< / p>

1 个答案:

答案 0 :(得分:1)

将评论转换为答案。

如果一个线程执行chdir()而另一个线程执行ftw()(或nftw()),则所有地狱都可能崩溃。在扫描目录时删除目录也可能会引起问题(但这可能是由另一个进程(更不用说其他线程)引起的。

可移植性是一个问题吗? fts(3)功能套件可能并非在所有地方都可用(BSD / macOS将该功能套件标记为“预期将包含在将来的IEEE Std 1003.1-1988('POSIX.1')修订版中”),这增加了其成为可能的可能性。可移植性,但不能保证— POSIX 2018中没有它 (见下文)

如果您在线程应用程序中,则可能需要使用FTS_NOCHDIR,或者要认真使用*at()函数来访问文件。

  

可移植性不是问题。因此,更改进程的工作目录(从不同线程)是唯一会导致不一致的事情吗?绝对路径是魔术吗? FTS_NOCHDIR是否可以解决此问题?

我不知道更改目录是否是遇到问题的唯一方法;这只是搞砸事情的一种相当重要的方法。如果您有两个线程或两个进程在工作,一个试图通过fts_read()等来扫描文件系统,另一个试图进行任意更改(例如将目录从树中的一个位置移动到另一个位置),那么在扫描代码进行的会计处理中,我可以看到各种混乱的机会-省略了本应计数的事物,对事物进行了两次计数,而本应仅计数一次。

我要提到nftw(),因为它还没有出现。与ftw()相比,它具有几个优点,但是线程安全性不是其中之一。因此,除了fts_read()ftw()的问题也困扰nftw()的问题之外,这基本上是一个问题。

请注意,scandir()会在不遍历层次结构的情况下读取并选择单个目录的内容。它是专为ftw()和朋友而设计的。这不是ftw()等人的简单替代。

似乎已考虑fts(3),但拒绝了POSIX:http://www.opengroup.org/platform/ballots/1003.1a.d14.crb.txt