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.