`select` sur le même disque à partir de plusieurs threads

Que se passera-t-il si j’appelle select sur le même descripteur de fichier ouvert à partir de plusieurs threads?

Est-ce documenté quelque part?

Selon la spécification de select POSIX 2008 , rien n’empêche deux threads d’appeler select en même temps.

Il est raisonnable de déduire que si les deux threads surveillent des ensembles de descripteurs de fichier qui se chevauchent et que certains des descripteurs de fichier communs deviennent lisibles ou inscriptibles ou que des erreurs sont diagnostiquées, les deux threads peuvent se retrouver avec un rapport indiquant que les descripteurs de fichier communs sont prêts. Cela ne peut être garanti; vous devez vous préoccuper de problèmes de synchronisation, et cela peut dépendre de la planification des threads, etc. Cela signifie également que l’un des threads peut ne pas trouver de données à lire sur un descripteur de fichier qu’il lui a été demandé de contenir, à l’autre fil est arrivé en premier. Tout octet de données donné sera lu par un seul des threads.

Selon la page de manuel Linux , select est une fonction thread-safe et un point d’annulation.

Sur certains systèmes d’exploitation Linux , un thread entrera avec succès dans select , tandis que les autres seront bloqués (le corps de select est une section critique). Quels que soient les descripteurs renvoyés au premier thread, le second thread qui entre avec succès dans la select va probablement se réveiller immédiatement avec le même jeu, car la select est une interface à déclenchement par niveau.

Ainsi, vous ne pouvez pas utiliser select pour sélectionner simultanément plusieurs ensembles de descripteurs de fichiers sous Linux .

Linux semble prendre en charge une exécution entièrement réentrante, démontrée avec ce programme de test:

 void * reader (void *arg) { int *fds = (int *)arg; struct timeval to = { 2, 0 }; fd_set rfds; FD_ZERO(&rfds); FD_SET(fds[0], &rfds); select(fds[0]+1, &rfds, 0, 0, &to); } int main () { int sp[2]; pthread_t t[2]; socketpair(AF_UNIX, SOCK_STREAM, 0, sp); pthread_create(&t[0], 0, reader, sp); pthread_create(&t[1], 0, reader, sp); pthread_join(t[0], 0); pthread_join(t[1], 0); return 0; } 

Lors du chronométrage de ce programme sous Linux (le mien était de 2.6.43), le programme est revenu après 2 secondes, indiquant que les deux threads entrés étaient select simultanément.