En tant qu'appel système pour fermer le descripteur de fichier
close()
Est fourni.
Par conséquent, j'écrirai sur les pièges de l'appel système fermé qui sont souvent négligés.
#include <unistd.h>
int close(int fd);
Par exemple, lors de l'appel d'un appel système d'E / S de fichier ou d'une fonction de bibliothèque
eintr
Est gênant, et il y a des cas où une erreur se produit lorsqu'un appel de fonction est interrompu.
EINTR Voir appel de fonction interrompu (POSIX.1); signal (7).
Référence: Manuel du programmeur Linux --ERRNO
Dans ce cas, même s'il échoue comme suit, s'il s'agit de EINTR
,
Il existe une solution de contournement pour fournir une fonction wrapper pour réessayer et éviter l'échec du traitement dans EINTR
.
/* wrapper function of send () */
ssize_t send_wrap(int sockfd, const void *buf, size_t len, int flags)
{
int res = 0;
do {
res = send(sockfd, buf, len, flags);
} while ((res == -1) && (errno == EINTR));
return res;
}
Il y a aussi un échec dû à ʻEINTR` dans close (). Cependant, les tentatives sur l'appel système ** close () sont dangereuses. ** **
Alors, pourquoi est-il dangereux de réessayer lorsque close () échoue? Par exemple, dans le cas du multithreading, il est possible de fermer le fd réutilisé par un autre thread.
Le noyau Linux publie fd au début du processus dans close (),
Le traitement qui peut provoquer une erreur est situé dans la seconde moitié de close ()
.
En d'autres termes, le processus est renvoyé comme une erreur, mais fd est ** libéré **, donc S'il est multi-thread, ** un autre thread peut réutiliser le fd **, Il existe un risque que ** le fichier fd soit fermé ** s'il est réessayé.
D'après ce qui précède, on peut dire qu'il vaut mieux ne pas réessayer l'appel système close ()
quand il échoue.
http://man7.org/linux/man-pages/man2/close.2.html
Recommended Posts