[Langage C] readdir () vs readdir_r ()

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`.

readdir () spécifications de readdir_r ()

Voyons pourquoi c'est le cas. Tout d'abord, vérifiez les spécifications de readdir () et readdir_r ().

Spécifications de readdir () (POSIX.1-2008)

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

Spécifications de readdir_r ()

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 */  
};

Problèmes causés par l'ambiguïté dans POSIX.1.

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.

Vue du côté Linux / glibc

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

readdir_r () / readdir64_r () est obsolète dans la glibc 2.24

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

Conclusion

De ce qui précède, au lieu d'utiliser `` readdir_r () '' même en multithreading readdir() +contrôle d'exclusionDoit être envisagé pour l'utilisation.

référence

http://mkosaki.blog46.fc2.com/blog-entry-1237.html http://blog.gachapin-sensei.com/archives/618834.html

Recommended Posts

[Langage C] readdir () vs readdir_r ()
File d'attente ALDS1_3_B langage C
[Algorithme de langage C] Endianness
Intégration du langage machine en langage C
Recherche binaire ALDS1_4_B langage C
PyTorch C ++ VS Python (édition 2019)
Recherche linéaire ALDS1_4_A en langage C
Test de module multi-instance en langage C
Pointeur de fonction et objdump ~ Langage C ~
Réaliser une classe d'interface en langage C
Ecriture du langage C avec Sympy (métaprogrammation)
Langage de programmation C à haute efficacité énergétique
Introduction à Protobuf-c (langage C ⇔ Python)
[Algorithme de langage C] arbre de recherche binaire
Langage C 8 reine résolution de problèmes 3 modèles
Segfo avec 16 caractères en langage C
Appeler le langage C depuis Python (python.h)