$ uname -a
Linux crowsnest 2.6.32-28-generic #55-Ubuntu SMP Mon Jan 10 23:42:43 UTC 2011 x86_64 GNU/Linux
$ man readdir:
说明
readdir()函数返回一个指向dirent结构的指针,该结构表示指向的目录流中的下一个目录条目。 dirp ......
... [剪断] ...
readdir_r()函数是readdir()的可重入版本...
... [剪断] ...
返回值
成功时,readdir()返回指向dirent结构的指针。 (此结构可以静态分配;不要尝试释放(3)它。)如果到达目录流的末尾,则返回NULL并且不更改errno。如果发生错误,则返回NULL并正确设置errno。
readdir_r()函数成功返回0。出错时,它返回正误差编号。如果到达目录流的末尾,则readdir_r()返回0,并在* result中返回NULL。
我对这意味着什么感到困惑,我的这个函数的应用是收集动态分配的结构指针数组,其中包含有关目录条目的数据,我想知道我是否可以动态分配dirent结构并设置指向他们的指针。但这一行接着说结果永远不应该被free释放,所以我想知道我是否应该分配一个单独的dirent结构,它将成为列表的一部分并将其存储在返回的结果中。
我也对上面手册页中“may”的术语感到困惑。这是否意味着它被静态分配,有时它不是。
我很熟悉(含糊地)静态变量在C中的意思,但不确定所有规则和可能的问题。因为我想传递目录中的dirent结构,我宁愿它是动态分配的。这是readdir_r的用途吗?或者将双指针设置为指向另一个静态分配的dirent结构?
并且我不完全确定在这个上下文中readdir_r的重入意味着什么。我对renetrant的理解只来自方案协同程序,我不确定它如何适用于读取unix目录。
答案 0 :(得分:7)
结构可能是静态分配的,可能是线程本地的,也可能是动态分配的。这取决于实施。但无论如何,这都不是你的自由,这就是为什么你不能释放它。
readdir_r
没有为你分配任何东西,你给它一个dirent
,分配你喜欢的东西,并填充它。因此,与调用相比,它确实可以省去一些努力readdir
并复制dir数据。这不是readdir_r
的主要目的,但它实际上 的能力是能够同时从不同的线程进行调用,这是readdir
无法做到的。 }。
“reentrant”实际意味着什么,该函数可以在之前的调用返回之前再次调用。一般来说,这可能意味着来自不同的线程(这是大多数人所说的“线程安全”),来自第一次调用期间发生的信号的处理程序,或者是由于递归。但是C标准没有线程概念,所以它提到“可重入”只意味着后两者。 Posix定义了“线程安全”来要求这种形式的重入和,此外,大多数人都认为是线程安全的。
在Posix中,要求线程安全的每个函数都需要是可重入的,并且readdir_r
必须是线程安全的。我认为较弱的意义上的重入与readdir_r
无关,因为它不会调用任何可能导致递归的用户代码,并且它不是异步信号安全的,因此不能从信号处理程序中调用它。
请注意,因为当某些人(Java程序员)说“线程安全”时,他们意味着该函数可以同时由不同的线程在相同的参数上调用,并将使用锁定正常工作。 Posix API并不意味着线程安全,它们只意味着可以同时在不同的数据上调用该函数。函数使用的任何全局数据都受锁或其他方式的保护,但参数不一定是。
答案 1 :(得分:6)
这意味着readdir可以有这样的东西:
struct dirent *
readdir(DIR *dirp)
{
static struct dirent;
/* Do stuff. */
return &dirent;
}
显然,释放它是违法的(,因为你没有通过malloc
获得它。)
标准并没有强迫任何人像这样做。实现可以使用自己的机制(稍后可能malloc
和free
)。
“可重入”意味着当我们在readdir_r
内时,可以再次安全地调用该函数(例如来自信号处理程序)。例如,readdir
不可重入。假设发生这种情况:
readdir(dir);
并开始修改dirent
dirent
,返回并且异步上下文继续运行dirent
包含哪些内容?Reentrant函数是天赐之物,它们总是可以安全地调用。
答案 2 :(得分:6)
此处的规则非常简单 - 您可以自由复制数据readdir()
返回,但是您不拥有将数据放入的缓冲区,因此您无法采取建议您的操作做。 (即,将数据复制到您自己的缓冲区;不要将指针存储在readdir拥有的缓冲区中。)
so I'm wondering if I should allocate a seperate dirent struct which will be part of the list and memcpy it over the returned result
- 这正是你应该做的。
I'm also confused by the terminology of "may" in the above man page. does this mean that somtimes it's statically allocated, and sometimes it's not.
- 这意味着您不能指望它将如何管理,但它将为您管理。细节可能因系统而异。
可重入意味着线程安全。 readdir()使用静态条目,使多个线程使用它们并不安全,就好像它们各自控制多次调用进程一样。 readdir_r()将使用调用者提供的已分配空间,让多个线程独立运行。