readdir() vs readdir_r()
En tant que fonction de lecture d'un répertoire
readdir()
/ readdir_r()
Deux fonctions sont fournies par la bibliothèque standard.
Si l'utilisation est à un seul thread, vous pouvez utiliser readdir () '', Si vous utilisez
readdir_r () '' qui est thread-safe en multithread
Il est raisonnable de penser que c'est bon.
En conclusion, readdir_r () '' ne doit pas être utilisé. En cas de multi-thread, il est préférable d'utiliser
readdir () + contrôle exclusif`
.
Voyons pourquoi c'est le cas. Tout d'abord, vérifiez les spécifications de readdir () et readdir_r ().
Dans POSIX.1-2008, la sécurité des threads de `` readdir () '' n'est pas garantie.
DESCRIPTION The readdir() function need not be thread-safe.
Référence: readdir, readdir_r --read a directory
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()
Référence: The Open Group Base Specifications Issue 7, 2018 edition --2.9.1 Thread-Safety
int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
readdir_r()
Lit l'entrée de répertoire suivante à partir du flux de répertoire dirp
L'entrée est stockée et renvoyée dans la mémoire tampon allouée par l'appelant pointé par l'entrée.
Un pointeur vers l'entrée renvoyée est stocké dans * result.
Lorsque la fin du flux d'annuaire est atteinte, NULL est stocké dans * result.
Sous Linux, la structure dirent est définie comme suit.
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 */
};
La taille du champ d_name n'est pas spécifiée dans POSIX.1 (* 1) Il peut y avoir d'autres champs non standard après d_name dans la structure dirent, donc Si vous utilisez readdir_r () dans une application portable, passez le tampon à l'entrée Il doit être attribué comme suit:
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) Dans Solaris, d_name est défini comme d_name [1].
Cependant, en raison de l'ambiguïté de la définition de la constante _PC_NAME_MAX, cette mesure ci-dessus Il a été souligné que cela entraînerait un dépassement de la mémoire tampon.
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.
Référence: readdir (3) - Page de manuel de Linux
De plus, readdir_r () et readdir64_r () sont obsolètes dans la glibc 2.24.
- The readdir_r and readdir64_r functions have been deprecated. It is recommended to use readdir and readdir64 instead.
Référence: Adhemerval Zanella - La version 2.24 de la bibliothèque GNU C est maintenant disponible
De ce qui précède, au lieu d'utiliser `` readdir_r () '' même en multithreading
readdir() +contrôle d'exclusion
Doit être envisagé pour l'utilisation.
http://mkosaki.blog46.fc2.com/blog-entry-1237.html http://blog.gachapin-sensei.com/archives/618834.html
Recommended Posts