readdir() vs readdir_r()
Als Funktion zum Lesen eines Verzeichnisses
readdir()
/ readdir_r()
Die Standardbibliothek bietet zwei Funktionen.
Wenn Sie einen einzelnen Thread verwenden, können Sie `readdir ()`
verwenden, aber
Wenn Sie `readdir_r ()`
verwenden, ist das Thread-sicher, wenn Multithreading ausgeführt wird
Es ist vernünftig zu denken, dass es gut ist.
Zusammenfassend sollte `readdir_r ()`
nicht verwendet werden.
Bei Multithreads ist es besser, `readdir () + exklusives Steuerelement
`zu verwenden.
Mal sehen, warum das so ist. Überprüfen Sie zunächst die Spezifikationen von readdir () und readdir_r ().
In POSIX.1-2008 ist die Thread-Sicherheit von `readdir ()`
nicht garantiert.
DESCRIPTION The readdir() function need not be thread-safe.
Referenz: readdir, readdir_r - ein Verzeichnis lesen
2.9.1 Thread-Safety All functions defined by this volume of POSIX.1-2017 shall be thread-safe, except that the following functions1 need not be thread-safe. readdir()
Referenz: Die Open Group Base-Spezifikationen, Ausgabe 7, Ausgabe 2018 --2.9.1 Thread-Sicherheit
int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
readdir_r()
Liest den nächsten Verzeichniseintrag aus dem Verzeichnis-Stream-Verzeichnis
Der Eintrag wird in dem Puffer gespeichert und zurückgegeben, den der Anrufer zugewiesen hat, auf den der Eintrag zeigt.
Ein Zeiger auf den zurückgegebenen Eintrag wird im * Ergebnis gespeichert.
Wenn das Ende des Verzeichnisstroms erreicht ist, wird NULL im Ergebnis * gespeichert.
Unter Linux ist die direkte Struktur wie folgt definiert.
struct dirent {
ino_t d_ino; /* inode number */
off_t d_off; /* not an offset; see NOTES */
unsigned short d_reclen; /* length of this record */
unsigned char d_type; /* type of file; not supported by all file system types */
char d_name[256]; /* filename */
};
Die Größe des Felds d_name ist in POSIX.1 (* 1) nicht angegeben. Nach d_name befinden sich möglicherweise andere nicht standardmäßige Felder in der Verzeichnisstruktur Wenn Sie readdir_r () in einer portablen Anwendung verwenden, übergeben Sie den Puffer an entry Es sollte wie folgt zugewiesen werden:
name_max = pathconf(dirpath, _PC_NAME_MAX);
if (name_max == -1) /* Limit not defined, or error */
name_max = 255; /* Take a guess */
len = offsetof(struct dirent, d_name) + name_max + 1;
entryp = malloc(len);
(* 1) In Solaris ist d_name als d_name [1] definiert.
Aufgrund der Mehrdeutigkeit der Konstantendefinition _PC_NAME_MAX ist diese obige Maßnahme jedoch Es wurde darauf hingewiesen, dass dies zu einem Pufferüberlauf führen wird.
In the current POSIX.1 specification (POSIX.1-2008), readdir() is not required to be thread-safe. However, in modern implementations (including the glibc implementation), concurrent calls to readdir() that specify different directory streams are thread-safe. In cases where multiple threads must read from the same directory stream, using readdir() with external synchronization is still preferable to the use of the deprecated readdir_r(3) function. It is expected that a future version of POSIX.1 will require that readdir() be thread- safe when concurrently employed on different directory streams.
Referenz: readdir (3) --Linux-Handbuchseite
Außerdem sind readdir_r () und readdir64_r () in glibc 2.24 veraltet.
- The readdir_r and readdir64_r functions have been deprecated. It is recommended to use readdir and readdir64 instead.
Referenz: Adhemerval Zanella - Die GNU C Library Version 2.24 ist jetzt verfügbar
Aus dem oben Gesagten, anstatt " readdir_r () "
`auch im Multithreading zu verwenden
readdir() +Ausschlusskontrolle
Sollte für die Verwendung in Betracht gezogen werden.
http://mkosaki.blog46.fc2.com/blog-entry-1237.html http://blog.gachapin-sensei.com/archives/618834.html
Recommended Posts