Als Systemaufruf zum Schließen des Dateideskriptors
close()
Wird gestellt.
Daher werde ich über die Fallstricke des engen Systemaufrufs schreiben, die oft übersehen werden.
#include <unistd.h>
int close(int fd);
Zum Beispiel beim Aufrufen eines Datei-E / A-Systemaufrufs oder einer Bibliotheksfunktion
eintr
Ist umständlich und es gibt Fälle, in denen ein Fehler auftritt, wenn ein Funktionsaufruf unterbrochen wird.
EINTR Siehe Funktionsaufruf unterbrochen (POSIX.1); Signal (7).
Referenz: Linux-Programmierhandbuch --ERRNO
In diesem Fall, selbst wenn es wie folgt fehlschlägt, wenn es "EINTR" ist, Es gibt eine Problemumgehung, um eine Wrapper-Funktion bereitzustellen, mit der erneut versucht werden kann, Verarbeitungsfehler in EINTR zu verhindern.
/* 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;
}
Es gibt auch einen Fehler aufgrund von EINTR in close (). Wiederholungsversuche beim Systemaufruf ** close () sind jedoch gefährlich. ** ** **
Warum ist es also gefährlich, es erneut zu versuchen, wenn close () fehlschlägt? Im Fall von Multithreading ist es beispielsweise möglich, den von einem anderen Thread wiederverwendeten fd zu schließen.
Der Linux-Kernel veröffentlicht fd früh im Prozess in close (), Die Verarbeitung, die einen Fehler verursachen kann, befindet sich in der zweiten Hälfte von "close ()".
Mit anderen Worten, der Prozess wird als Fehler zurückgegeben, aber fd wird ** freigegeben **, also Wenn es sich um ein Multithreading handelt, ** verwendet ein anderer Thread möglicherweise das fd **, Es besteht die Gefahr, dass ** der fd geschlossen wird **, wenn er erneut versucht wird.
Aus dem Obigen kann gesagt werden, dass es besser ist, den Systemaufruf "close ()" nicht erneut zu versuchen, wenn er fehlschlägt.
http://man7.org/linux/man-pages/man2/close.2.html