假设一个线程程序正在执行文件系统操作(遍历,读取,创建,删除,移动目录和文件)。
根据an answer,ftw()
在这种情况下不安全。 (另外,ftw()
需要全局变量,这看起来并不太优雅。)
我应该使用fts_open()
/ fts_children()
/ fts_read()
吗?或许scandir()
?
使用ftw()
(某些线程正在使用ftw()
来聚合数据而另一个线程正在删除/移动某些数据)的线程程序是不安全的,确切地说,为什么?< / p>
答案 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