$ uname -a
Linux crowsnest 2.6.32-28-generic #55-Ubuntu SMP Mon Jan 10 23:42:43 UTC 2011 x86_64 GNU/Linux
Run Code Online (Sandbox Code Playgroud)
$ 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目录.
结构可能是静态分配的,可能是线程本地的,也可能是动态分配的.这取决于实施.但无论如何,这不是你的自由,这就是为什么你不能释放它.
readdir_r你不分配任何东西,你给它一个dirent,但是分配你喜欢,它在填充它.因此它不保存你打电话相比,一点点努力readdir和复制DIR数据.这不是主要目的readdir_r,但是,它实际上是对是使从在同一时间不同的线程,你不能做呼叫的能力readdir.
"可重入"实际意味着,该函数可以在之前的调用返回之前再次调用.在一般情况下,这可能会从不同的线程平均(这是大多数人的"线程安全"的意思),从第一次调用期间发生的一个信号的处理程序,或由于递归.但是C标准没有线程概念,所以它提到"可重入"只意味着后两者.POSIX定义"线程安全",要求这种形式重入的和,此外,大多数人通过线程安全的意思的东西.
在Posix中,每个需要线程安全的功能都需要是可重入的,并且readdir_r必须是线程安全的.我认为在较弱的意义上的重入是无关紧要的readdir_r,因为它不会调用任何可能导致递归的用户代码,并且它不是异步信号安全的,所以它也不能从信号处理程序中调用.
请注意,因为当某些人(Java程序员)说"线程安全"时,他们意味着该函数可以由同一个参数上的不同线程同时调用,并且将使用锁来正常工作.Posix API并不意味着线程安全,它们只意味着可以同时在不同的数据上调用该函数.函数使用的任何全局数据都受锁或其他方式的保护,但参数不必是.
这意味着readdir可能有这样的东西:
struct dirent *
readdir(DIR *dirp)
{
static struct dirent;
/* Do stuff. */
return &dirent;
}
Run Code Online (Sandbox Code Playgroud)
显然,释放它是违法的(因为你没有通过它获得它malloc).
该标准并没有强迫任何人像这样做.实现可能使用其自己的机制(也许malloc和free后来对自己).
"可重入"意味着当我们进入内部时readdir_r,可以再次安全地调用该函数(例如,从信号处理程序).例如,readdir不是可重入的.假设发生这种情况:
readdir(dir);,它开始修改direntdirent,返回和异步上下文继续进行dirent包含?可重入的功能是天赐之物,它们始终可以安全地呼叫.
这里的规则是非常简单的-你可以自由地进行数据的拷贝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()将使用调用者提供的已分配空间,让多个线程独立运行.