[LINUX] [C-Sprache] Close () Es ist gefährlich, es erneut zu versuchen, wenn es fehlschlägt

Einführung

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);

EINTR lädt Sie zu einer Falle ein

Zum Beispiel beim Aufrufen eines Datei-E / A-Systemaufrufs oder einer Bibliotheksfunktion eintrIst 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. ** ** **

Wiederholungsrisiko, wenn close () fehlschlägt

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.

Fazit

Aus dem Obigen kann gesagt werden, dass es besser ist, den Systemaufruf "close ()" nicht erneut zu versuchen, wenn er fehlschlägt.

Referenz

http://man7.org/linux/man-pages/man2/close.2.html

Recommended Posts

[C-Sprache] Close () Es ist gefährlich, es erneut zu versuchen, wenn es fehlschlägt
Einführung in Protobuf-c (C-Sprache ⇔ Python)
Wenn Sie es so verwenden möchten, wie es ist, wenn Sie es mit Lambda-Memo verwenden
Es ist besser, den Weight Initializer zu verwenden, wenn Sie mit HeNormal mit Chainer initialisieren
Es war gefährlich, beim Generieren einer symbolischen Verknüpfung einen relativen Pfad anzugeben
Was ist eine C-Sprachbibliothek? Welche Informationen sind für die Öffentlichkeit zugänglich?
Bequem zum Verwenden von Ebenen beim Laden von Bibliotheken auf Lambda
Wird nicht empfohlen, pip direkt zu verwenden?
Es ist bequemer, csv-table zu verwenden, wenn Sie eine Tabelle mit Python-Sphinx schreiben
[OpenCV] Wenn Sie überprüfen möchten, ob es mit imread richtig gelesen wird