假设一个线程程序正在执行文件系统操作(遍历、读取、创建、删除、移动目录和文件)。
根据an answerftw()在这种情况下是不安全的。(而且,ftw()需要全局变量,这看起来不太优雅。)
我应该改用fts_open()/fts_children()/fts_read()吗?或者scandir()
对于使用ftw()的线程程序(有些线程使用ftw()来聚集数据,而另一个线程正在删除/移动某些数据),究竟什么是不安全的?为什么?

最佳答案

将评论转换为答案。
如果一个线程执行chdir(),而另一个线程执行ftw()(或nftw()),所有的shell都可能崩溃。在扫描目录时删除该目录也可能导致问题(但这可能发生在另一个进程中,更不用说其他线程了)。
可移植性是个问题吗?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()和friends的工作而设计的。它不是对scandir()等的简单替代品。
看起来ftw()被考虑了,但是POSIX被拒绝了:http://www.opengroup.org/platform/ballots/1003.1a.d14.crb.txt

10-01 19:19