Thanks for reading this question, I only have basic C knowledge and I am not familiar with linux system. Here is what i know about readdir:
struct dirent* readdir() {
static struct dirent; //read action
return &dirent;
}
My question:
i did not see any static varible in glibc source code, where is the static varible?
There is no static variable. The code you pointed to uses a buffer in the directory stream to hold and return struct dirent
objects. So it is unsafe to use multiple threads with the same directory stream because they could conflict over use of the single buffer.
I try to use multi thread to read same dirstream such as: DIR* des_dir=opendir(xxx); pthread_create(pid,0,custom_readdir,des_dir); Each thread shares the same dirstream, and the result is OK. Each thread outputs part of the directory correctly,…
You got unlucky in your experiment; the execution of the threads happened to fail to conflict. The buffer used does have room for multiple struct dirent
, allowing some opportunity for multiple threads to use different parts, making observation of a failure less likely, especially when testing with only a few directories.
If readdir() is indeed unsafe, how can I read a directory in a safe way?
Open a separate directory stream for each thread. Or use one thread to read the directory stream and have it copy the desired directory information and pass it to other threads to do the work for the directories.
If readdir() is indeed unsafe, how can I read a directory in a safe way?
In all POSIXy systems, you can use scandir()
, scandirat()
, glob()
, and nftw()
. nftw()
is the best option for traversing entire directory trees (looking for specific files), scandir()
/ scandirat()
for scanning individual directories.
Of these, scandir()
and scandirat()
are thread-safe; and nftw()
is thread-safe except wrt. current working directory during traversal.
In Linux and BSDs, you can also use the <fts.h>
functions.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.